├── .gitignore ├── .nvmrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── THIRD_PARTY_LICENSES.txt ├── ci.hocon ├── graalvm-pack ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── graalvm-pack-logo.png ├── package.json └── vsc-extension-quickstart.md ├── graalvm ├── .eslintrc.js ├── .nvmrc ├── .vscode │ ├── extensions.json │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── images │ ├── debugging_ni_vscode.png │ ├── graalvm-logo.png │ ├── graalvm_install_actions.png │ ├── gutter-dark-green.svg │ ├── gutter-dark-red.svg │ ├── gutter-light-green.svg │ ├── gutter-light-red.svg │ ├── langs_vscode.png │ ├── proxyOn.png │ ├── run.png │ └── supported_languages.png ├── package-lock.json ├── package.json ├── resources │ └── graalvm.svg ├── sl-language-configuration.json ├── snippets │ ├── js-polyglot-snippets.json │ ├── python-polyglot-snippets.json │ ├── r-polyglot-snippets.json │ ├── ruby-polyglot-snippets.json │ └── sl-polyglot-snippets.json ├── src │ ├── extension.ts │ ├── gdsUtils.ts │ ├── graalVMConfiguration.ts │ ├── graalVMCoverage.ts │ ├── graalVMDebug.ts │ ├── graalVMDebugAdapter.ts │ ├── graalVMDebugInterfaces.d.ts │ ├── graalVMInstall.ts │ ├── graalVMLanguageServer.ts │ ├── graalVMLicenseCheck.ts │ ├── graalVMNativeImage.ts │ ├── graalVMPython.ts │ ├── graalVMR.ts │ ├── graalVMRuby.ts │ ├── sdkmanSupport.ts │ ├── types.ts │ └── utils.ts ├── syntaxes │ ├── js-polyglot-injection.json │ ├── python-polyglot-injection.json │ ├── r-polyglot-injection.json │ ├── ruby-polyglot-injection.json │ ├── sl-polyglot-injection.json │ └── sl.tmLanguage.json ├── tsconfig.eslint.json ├── tsconfig.json ├── vsc-extension-quickstart.md ├── webpack.config.js └── webviews │ ├── icons │ ├── law_dark.png │ └── law_light.png │ ├── licenseCheck.html │ ├── scripts │ └── licenseCheck.js │ └── styles │ └── licenseCheck.css ├── mx.vscode ├── mx_vscode.py └── suite.py └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | **/dist 3 | **/out 4 | **/node_modules 5 | **/.vscode-test/ 6 | **/*.vsix 7 | package-lock.json 8 | /mxbuild 9 | /.project 10 | .DS_Store 11 | .gitignore 12 | /nbcode-graalvm/nbcode-graalvm-ojdbc/target/ 13 | /graalvm/nbcode/ 14 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v14.16.0 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | To submit pull requests to vscode-extensions, you need to sign the [Oracle Contributor 2 | Agreement][1]. 3 | 4 | Project members with write access to the repository will determine 5 | and assign an appropriate [Assignee][2] for the pull request. The 6 | assignee will work with the pull request owner to address any issues 7 | and then merge the pull request. 8 | 9 | [1]: http://www.oracle.com/technetwork/community/oca-486395.html 10 | [2]: https://help.github.com/articles/assigning-issues-and-pull-requests-to-other-github-users/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code extension 2 | 3 | This suite provides extension to Visual Studio Code that supports development of applications targeting GraalVM. 4 | The extension is Technology Preview. 5 | 6 | ## Build VSIX package from sources 7 | 8 | To build VSIX package of the GraalVM extension, take the following steps: 9 | 10 | * Install `vsce` (short for "Visual Studio Code Extensions"), a command-line tool for packaging, publishing and managing VS Code extensions 11 | ```bash 12 | npm install -g vsce 13 | ``` 14 | 15 | * Compile and package the extension 16 | ```bash 17 | pushd graalvm; npm install; vsce package; popd; 18 | ``` 19 | 20 | Alternatively, invoke `mx build` to create a zip file distribution with the extension contained. 21 | 22 | ## Installation 23 | 24 | To install the GraalVM extension into Visual Studio Code, take the following step: 25 | 26 | * Install desired package with `code --install-extension ` 27 | ```bash 28 | code --install-extension graalvm/graalvm-*.vsix 29 | ``` 30 | ## License 31 | 32 | GraalVM VS Code Extension is licensed under [The Universal Permissive License (UPL), Version 1.0](LICENSE) -------------------------------------------------------------------------------- /ci.hocon: -------------------------------------------------------------------------------- 1 | mx : { 2 | packages : { 3 | mx: "HEAD" 4 | } 5 | } 6 | 7 | oraclejdk11 : { 8 | downloads : { 9 | JAVA_HOME : {"name": "labsjdk", "version": "ce-11.0.12+5-jvmci-21.3-b01", "platformspecific": true } 10 | } 11 | } 12 | 13 | common : ${mx} ${oraclejdk11} { 14 | timelimit : "30:00", 15 | catch_files : [ 16 | "Graal diagnostic output saved in (?P.+\.zip)" 17 | ], 18 | environment: { 19 | npm_config_registry: "https://artifacthub-phx.oci.oraclecorp.com/api/npm/npm-virtual/" 20 | } 21 | } 22 | 23 | linux : ${common} { 24 | packages: { 25 | nodejs : ">=14.16.0" 26 | maven: ">=3.6.3" 27 | } 28 | } 29 | 30 | darwin : ${common} { 31 | } 32 | 33 | windows : ${common} { 34 | } 35 | 36 | linux-amd64 : ${linux} { 37 | capabilities : [linux, amd64], 38 | docker: { 39 | "image": "phx.ocir.io/oraclelabs2/c_graal/buildslave:buildslave_ol7", # Use this docker image 40 | "mount_modules": true 41 | } 42 | } 43 | 44 | darwin-amd64 : ${darwin} { 45 | capabilities : [darwin, amd64] 46 | } 47 | 48 | windows-amd64 : ${windows} { 49 | capabilities : [windows, amd64] 50 | } 51 | 52 | vscodeCommon: { 53 | timelimit : "30:00" 54 | } 55 | 56 | vscodeBuildGate : ${vscodeCommon} { 57 | targets : [ gate ], 58 | run : [ 59 | ["mx", "gate"] 60 | ] 61 | } 62 | 63 | builds += [ 64 | ${linux-amd64} ${vscodeBuildGate} { name: "gate-vscode-build" }, 65 | ] 66 | -------------------------------------------------------------------------------- /graalvm-pack/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | vsc-extension-quickstart.md 5 | -------------------------------------------------------------------------------- /graalvm-pack/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Version 0.0.3 4 | * Documentation improvements 5 | 6 | ## Version 0.0.2 7 | * Renamed to "GraalVM Extension Pack for Java" 8 | 9 | ## Version 0.0.1 10 | * Initial release published on Visual Studio Marketplace -------------------------------------------------------------------------------- /graalvm-pack/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. -------------------------------------------------------------------------------- /graalvm-pack/README.md: -------------------------------------------------------------------------------- 1 | # GraalVM Extension Pack for Java 2 | 3 | [GraalVM Extension Pack for Java](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.graalvm-pack) is a collection of extensions that helps you write, debug and test Java, JavaScript, Python, Ruby, R and polyglot applications running on GraalVM, either standalone or using the Micronaut framework. 4 | GraalVM Extension Pack for Java bundles [GraalVM Tools for Java](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.graalvm), [GraalVM Tools for Micronaut](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.micronaut), and [Apache NetBeans Language Server](https://marketplace.visualstudio.com/items?itemName=asf.apache-netbeans-java) extensions. 5 | The extension is Technology Preview. 6 | 7 | ### Java Development Support 8 | 1. Full featured Java development (edit-compile-debug & test cycle) for Maven and Gradle projects in VS Code. 9 | 2. Support for Java 8 up to the latest Java releases 10 | 3. JUnit and TestNG test frameworks support 11 | 12 | ### GraalVM Development Support 13 | 1. GraalVM Polyglot debugging mixing Java and/or GraalVM guest languages 14 | 2. Native Image debugging using GDB and Java source code 15 | 3. GraalVM guest languages support 16 | 17 | ### Micronaut Development Support 18 | 1. Integrated Micronaut project wizard 19 | 2. Micronaut __Run Continuos Mode__ support 20 | 3. Micronaut configuration files (YAML) code navigation support 21 | 22 | ## Extensions Included 23 | 24 | * [GraalVM Tools for Java](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.graalvm) - an extension which provides a full-fledged support for the Java language and makes the VS Code a friendly and comfortable development environment for GraalVM users. It allows to easily download and manage multiple GraalVM installations and integrate them into the VS Code as a JDK platform, and enables all the unique GraalVM scripting and polyglot features. 25 | * [GraalVM Tools for Micronaut](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.micronaut) - an extension which adds support for the Micronaut framework in the VS Code development environment. The extension has been designed to cooperate with the GraalVM extension for a smooth Micronaut applications development, including debugging and building native images with GraalVM. 26 | * [Apache NetBeans Language Server](https://marketplace.visualstudio.com/items?itemName=asf.apache-netbeans-java) - an extension which uses the Apache NetBeans engine to deliver full support for Java 8 and higher in VS Code: code completion, hints, refactorings, go-to definition, Javadoc on hover, and full support for Maven and Gradle projects. The extension provides a Java 8+ debugger which is also capable of debugging polyglot calls to JavaScript, Python, Ruby or R when running on GraalVM. 27 | 28 | ### Feedback 29 | 30 | * [Request a feature](https://github.com/graalvm/vscode-extensions/issues/new?labels=enhancement) 31 | * [File a bug](https://github.com/graalvm/vscode-extensions/issues/new?labels=bug) 32 | 33 | ### Privacy Policy 34 | 35 | Please read the [Oracle Privacy Policy](https://www.oracle.com/legal/privacy/privacy-policy.html) to learn more. 36 | -------------------------------------------------------------------------------- /graalvm-pack/graalvm-pack-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm-pack/graalvm-pack-logo.png -------------------------------------------------------------------------------- /graalvm-pack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graalvm-pack", 3 | "displayName": "GraalVM Extension Pack for Java", 4 | "description": "VS Code extensions for development of polyglot Java, JavaScript, Python, Ruby, R, and Micronaut applications based on GraalVM.", 5 | "version": "0.0.4", 6 | "preview": true, 7 | "license": "SEE LICENSE IN LICENSE.txt", 8 | "publisher": "oracle-labs-graalvm", 9 | "author": { 10 | "name": "Oracle Labs" 11 | }, 12 | "icon": "graalvm-pack-logo.png", 13 | "homepage": "https://github.com/graalvm/vscode-extensions/blob/master/graalvm-pack/README.md", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/graalvm/vscode-extensions.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/graalvm/vscode-extensions/issues" 20 | }, 21 | "engines": { 22 | "vscode": "^1.49.0" 23 | }, 24 | "categories": [ 25 | "Extension Packs" 26 | ], 27 | "extensionDependencies": [ 28 | "oracle-labs-graalvm.graalvm" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /graalvm-pack/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension Pack 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension pack. 6 | * `package.json` - this is the manifest file that defines the list of extensions of the extension pack. 7 | 8 | ## Get up and running straight away 9 | 10 | * Press `F5` to open a new window with your extension loaded. 11 | * Open `Extensions Viewlet` and check your extensions are installed. 12 | 13 | ## Make changes 14 | 15 | * You can relaunch the extension from the debug toolbar after making changes to the files listed above. 16 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 17 | 18 | ## Install your extension 19 | 20 | * To start using your extension with Visual Studio Code copy it into the `/.vscode/extensions` folder and restart Code. 21 | * To share your extension with the world, read on https://code.visualstudio.com/docs about publishing an extension. 22 | -------------------------------------------------------------------------------- /graalvm/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* 2 | 👋 Hi! This file was autogenerated by tslint-to-eslint-config. 3 | https://github.com/typescript-eslint/tslint-to-eslint-config 4 | 5 | It represents the closest reasonable ESLint configuration to this 6 | project's original TSLint configuration. 7 | 8 | We recommend eventually switching this configuration to extend from 9 | the recommended rulesets in typescript-eslint. 10 | https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md 11 | 12 | Happy linting! 💖 13 | */ 14 | module.exports = { 15 | "env": { 16 | "es6": true, 17 | "node": true 18 | }, 19 | "parser": "@typescript-eslint/parser", 20 | "parserOptions": { 21 | "project": "tsconfig.eslint.json", 22 | "tsconfigRootDir": __dirname, 23 | "sourceType": "module" 24 | }, 25 | "plugins": [ 26 | "@typescript-eslint" 27 | ], 28 | "root": true, 29 | "rules": { 30 | "@typescript-eslint/member-delimiter-style": [ 31 | "warn", 32 | { 33 | "multiline": { 34 | "delimiter": "semi", 35 | "requireLast": true 36 | }, 37 | "singleline": { 38 | "delimiter": "semi", 39 | "requireLast": false 40 | } 41 | } 42 | ], 43 | "@typescript-eslint/naming-convention": "off", 44 | "@typescript-eslint/no-unused-expressions": "warn", 45 | "@typescript-eslint/semi": [ 46 | "warn", 47 | "always" 48 | ], 49 | "curly": "off", 50 | "eqeqeq": [ 51 | "warn", 52 | "always" 53 | ], 54 | "no-redeclare": "warn", 55 | "no-throw-literal": "warn", 56 | "no-unused-expressions": "off", 57 | "semi": "off" 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /graalvm/.nvmrc: -------------------------------------------------------------------------------- 1 | v14.16.0 -------------------------------------------------------------------------------- /graalvm/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint", 6 | "vscjava.vscode-maven", 7 | "asf.apache-netbeans-java", 8 | "ms-python.python", 9 | "REditorSupport.r", 10 | "rebornix.Ruby" 11 | ] 12 | } -------------------------------------------------------------------------------- /graalvm/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 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 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/dist/**/*.js" 18 | ], 19 | "preLaunchTask": "npm: webpack" 20 | }, 21 | { 22 | "type": "node", 23 | "request": "launch", 24 | "name": "Run Debug Adapter", 25 | "program": "${workspaceFolder}/src/graalVMDebugAdapter.ts", 26 | "args": [ 27 | "--server=4711" 28 | ], 29 | "outFiles": [ 30 | "${workspaceFolder}/dist/**/*.js" 31 | ], 32 | "preLaunchTask": "npm: compile" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /graalvm/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off", 11 | "java.completion.enabled": false 12 | } -------------------------------------------------------------------------------- /graalvm/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /graalvm/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | node_modules/** 4 | out/** 5 | src/** 6 | .gitignore 7 | vsc-extension-quickstart.md 8 | webpack.config.js 9 | **/tsconfig.json 10 | **/tslint.json 11 | **/*.map 12 | **/*.ts -------------------------------------------------------------------------------- /graalvm/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Version 0.5.31 4 | * VisualVM view now points to the new VisualVM for VS Code extension 5 | 6 | ## Version 0.5.30 7 | * Bug fixes in command line processing & project identification 8 | 9 | ## Version 0.5.29 10 | * Changes to work with GraalVM JDK 21 (23.1) which has no Graal Updater 11 | * Starting with GraalVM JDK 21 (23.1) in Sept 2023 there are __no installable components__ 12 | * VisualVM integration disabled 13 | 14 | ## Versuin 0.5.28 15 | * No longer includes Oracle JDBC driver for NetBeans Language Server. Use "GCN Database Support" extension to get database support. 16 | 17 | ## Version 0.5.27 18 | * Dependencies updated 19 | * Fixed: Registering GraalVM when no workspace is opened failed 20 | 21 | ## Version 0.5.26 22 | * Update of 3rd party libraries 23 | 24 | ## Version 0.5.25 25 | * Tokenless download from GDS service 26 | * Update of 3rd party libraries 27 | 28 | ## Version 0.5.24 29 | * Don't set JAVA_HOME to `/usr` on macOS 30 | * Get Java project packages from MS Java Ext Pack 31 | * Removed dependency on Apache NetBeans Language Server for Java 32 | * Register GraalVM as JDK for MS Java Ext Pack 33 | 34 | ## Version 0.5.23 35 | * Update of 3rd party libraries 36 | * Updated documentation 37 | * VisualVM and Native image agent launcher work with MS Java Ext pack 38 | * Clean up of java8+ launchers 39 | 40 | ## Version 0.5.22 41 | * Prevent `403 Forbidden` while trying to verify native-image-maven-plugin 42 | * Improved messages when working with Native Image Plugin 43 | * Update of 3rd party libraries 44 | 45 | ## Version 0.5.21 46 | * Do not use `'*'` for GraalVM VSCode extension activation 47 | * Debug Adapter Protocol is the default over Chrome Inspector 48 | * GDS URL can be customized via Settings. 49 | 50 | ## Version 0.5.20 51 | * Update of terser npm to v. 5.14.12 due to CVE-2022-25858 52 | * Allow for run without debugging for launch configurations with the Debug Adapter protocol specified 53 | 54 | ## Version 0.5.19 55 | * Special preconfigured terminal for building native image on Windows. GraalVM 22.2.0 and later is required 56 | 57 | ## Version 0.5.18 58 | * GraalVM settings like `graalvm.home` are Remote SSH aware 59 | * Documentation updates 60 | 61 | ## Version 0.5.17 62 | * Disable VisualVM integration for Remote SSH development sessions 63 | 64 | ## Version 0.5.16 65 | * Installs Oracle JDBC driver to NetBeans Language Server 66 | * Native Image control panel added to the Gr view, providing settings for the Native Image Agent in the first version 67 | * GraalVM Insight Heap replay functionality added 68 | * Image pull secret fixed for Kubernetes debugging 69 | * Proxy settings fixes for GDS service 70 | 71 | ## Version 0.5.15 72 | * Oracle DB JDBC driver installed 73 | * Setting GraalVM as JAVA_HOME improved for terminal,... 74 | * Documentation improvements 75 | * Option `graalvm.languageServer.start` for switching off the GraalVM Language Server added 76 | * Fixed download of GraalVM binaries 77 | ## Version 0.5.14 78 | * Thread dump / Heap dump / CPU sampler commands for the NBLS process to enable quick troubleshooting 79 | * SDKMan support fixes 80 | * README.MD improvements 81 | 82 | ## Version 0.5.13 83 | * Read GraalVM CE releases using GitHub API 84 | 85 | ## Version 0.5.12 86 | * Add GraalVM installed by system utility like yum 87 | * Number of stability improvements 88 | 89 | ## Version 0.5.11 90 | * Guess the GraalVM target directory before download of binary starts 91 | 92 | ## Version 0.5.10 93 | * Added remote K8s debugger 94 | * Support GraalVM installations without GU, e.g. yum managed 95 | * Other improvements in GraalVM installations handling 96 | 97 | ## Version 0.5.9 98 | * Integration with VisualVM in GraalVM activity panel. Requires GraalVM 21.2.0 or newer 99 | * Support for running projects with Native Image Agent 100 | * Added dependency on "asf.apache-netbeans-java" extension 101 | * Renamed to "GraalVM Tools for Java" 102 | 103 | ## Version 0.5.8 104 | * Security: updated dependencies 105 | 106 | ## Version 0.5.7 107 | * Support for SDKMAN installations 108 | 109 | ## Version 0.5.6 110 | * MacOS SDKMAN installation path support 111 | 112 | ## Version 0.5.5 113 | * Various improvements and fixes for GraalVM components management 114 | 115 | ## Version 0.5.4 116 | * Check writable permission before GraalVM is downloaded 117 | * Fix injectTos and scopeNames 118 | * User has to always accept GraalVM EE license 119 | 120 | ## Version 0.5.3 121 | * GraalVM EE JDK 11 bits are not offered for download 122 | 123 | ## Version 0.5.2 124 | * Bug fixes 125 | * Repository moved 126 | 127 | ## Version 0.5.0 128 | * GraalVM DAP support added 129 | * GraalVM installations management added 130 | * GraalVM EE download supported 131 | * GraalVM for Windows supported 132 | 133 | ## Version 0.0.10 134 | * Usability improvements 135 | 136 | ## Version 0.0.9 137 | * Bug fixes 138 | 139 | ## Version 0.0.8 140 | * Support Python, R, and Ruby languages merged from their separate extensions 141 | * Code coverage support added 142 | 143 | ## Version 0.0.7 144 | * Security: updated dependencies 145 | 146 | ## Version 0.0.6 147 | * Documentation enhanced 148 | 149 | ## Version 0.0.5 150 | * GraalVM LSP support added 151 | 152 | ## Version 0.0.4 153 | * Published on Visual Studio Marketplace 154 | 155 | ## Version 0.0.3 156 | * Support for Simple Language polyglot embeddings added 157 | * Basic support for native-image added 158 | 159 | ## Version 0.0.2 160 | * Basic editor support for Simple Language added 161 | * Lauch configuration for polyglot applications added 162 | * Code snippets for polyglot programming added 163 | 164 | ## Version 0.0.1 165 | * Initial release -------------------------------------------------------------------------------- /graalvm/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. -------------------------------------------------------------------------------- /graalvm/README.md: -------------------------------------------------------------------------------- 1 | # GraalVM Tools for Java Extension 2 | *** **Technology Preview** *** 3 | 4 | ## Features 5 | 6 | The extension helps you to manage GraalVM Installations and their components by VS Code. It includes the GraalVM Installation and Configuration Wizard. 7 | 8 | Setting GraalVM as the default Java runtime in VS Code enables both just-in-time ([Graal](http://www.graalvm.org/reference-manual/java/compiler.md)) and ahead-of-time ([Native Image](http://www.graalvm.org/reference-manual/native-image/README.md)) compilers. 9 | 10 | The GraalVM Tools for Java extension performs the work of several extensions in one. 11 | 12 | Key features include: 13 | * The [GraalVM installations manager](#graalvm-wizard) 14 | * The just-in-time Graal compiler, ensuring your code runs fast 15 | * The ahead-of-time compiler (provided by GraalVM [Native Image](#native-image)) to turn your Java application into a tiny native executable, perfect for deploying to the cloud 16 | * [Debugging of Native Image](#native-debugging) processes at run time 17 | * Native support for the Micronaut framework 18 | 19 | > Note: The extension is a Technology Preview. 20 | 21 | ## Requirements 22 | 23 |
24 | Java Development and Debugging 25 | 26 | [Extension Pack for Java from Microsoft](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack) has to be installed to develop Java. 27 | 28 | The [Apache NetBeans Language Server](https://marketplace.visualstudio.com/items?itemName=ASF.apache-netbeans-java) enables Java language support as well. If VS Code detects the Extension Pack for Java from Microsoft installed, it deactivates the Apache NetBeans Language Server. 29 |
30 | 31 |
32 | Proxy Settings 33 | If you are working behind a firewall, set the proxy for the GraalVM Installation Wizard and components installation. The extension will ask for setting this initially. Set: 34 | 1. __Http: Proxy:__ to the proxy server and port 35 | 2. __Http: Proxy Support: on__ when behind a firewall and __OFF__ when working without the proxy. 36 | 37 | For more information about GraalVM's installation and setup, consult the [extension documentation](https://www.graalvm.org/dev/tools/vscode/graalvm-extension/#graalvm-installation-wizard). 38 |
39 | 40 | ## Usage 41 | 42 |
43 | GraalVM Installation Wizard 44 | 45 | After installing the extension, you can install GraalVM by using the built-in installation wizard (click the **Gr** icon in the left side Activity Bar). 46 | 47 | You can either add an existing GraalVM installation (if you already have GraalVM), or download it directly from within VS Code. 48 | The **Download & Install GraalVM** action is recommended as it eliminates the fuss around setting environment variables and prepares the GraalVM runtime in VS Code for you. 49 | Choose either the Community distribution (free for all purposes) or Enterprise distribution (free for evaluation and development). You can also choose to install additional components (such as JavaScript and Node.js support). 50 | 51 | ![GraalVM Install Dialog](images/graalvm_install_actions.png) 52 |
53 | 54 |
55 | Support for Micronaut 56 | 57 | The GraalVM Tools for Java extension in combination with the [GraalVM Tools for Micronaut](https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.micronaut) extension brings native support for the Micronaut framework in VS Code and opens many more possibilities for Java developers. See the [Micronaut extension documentation](https://www.graalvm.org/dev/tools/vscode/micronaut-extension/) to learn more. 58 |
59 | 60 |
61 | GraalVM Native Image 62 | 63 | With the GraalVM Tools for Java extension you can compile your Java application into a native executable using [GraalVM Native Image](https://www.graalvm.org/reference-manual/native-image/) 64 | directly in VS Code. The advantages are many: 65 | * Your application is compiled into a small executable file, using a fraction of customary resources - so it runs lightning fast. 66 | * Your application achieves fast startup and peak performance with no warmup time. 67 | * Your application has improved security by greatly reducing attack surfaces and thwarting reverse engineering. 68 | 69 | Learn how you can do that from the [extension documentation](https://www.graalvm.org/dev/tools/vscode/graalvm-extension/#native-image-building-and-debugging). 70 |
71 | 72 |
73 | Native Image Debugging 74 | 75 | The GraalVM Tools for Java extension provides Java-like debugging of a native executable in a running state directly from within VS Code. 76 | You can set breakpoints, inspect the state of your application, even attach the debugger to a [Native Image](#native-image) process in VS Code and step over the Java application source code! 77 | 78 | Read more about this and find a demo application in the [Native Image Debugging guide](https://www.graalvm.org/dev/tools/vscode/graalvm-extension/debugging-native-image/). 79 |
80 | 81 | ## Available Commands 82 | | Name | Description | 83 | |---|---| 84 | | `extension.graalvm.selectGraalVMHome` | Select Active [GraalVM](#graalvm-wizard) Installation to be used. | 85 | | `extension.graalvm.installGraalVM` | Download & Install [GraalVM](#graalvm-wizard). | 86 | | `extension.graalvm.addExistingGraalVM` | Add Existing [GraalVM](#graalvm-wizard) to installations panel. | 87 | | `extension.graalvm.refreshInstallations` | Refresh [GraalVM](#graalvm-wizard) Installations panel. | 88 | | `extension.graalvm.installGraalVMComponent` | Download & Install [GraalVM](#graalvm-wizard) Component. | 89 | | `extension.graalvm.uninstallGraalVMComponent` | Uninstall [GraalVM](#graalvm-wizard) Component. | 90 | | `extension.graalvm.removeInstallation` | Remove [GraalVM](#graalvm-wizard) Installation from Installation panel and optionally Uninstall. | 91 | | `extension.graalvm.gds.showConfiguration` | Show GU Configuration for [GraalVM](#graalvm-wizard) download access. | 92 | | `extension.graalvm.addNativeImageToPOM` | Add [Native Image](#native-image) Plugin to Maven POM file. | 93 | | `extension.graalvm.toggleCodeCoverage` | Toggle Code Coverage. | 94 | | `extension.graalvm.installRLanguageServer` | Install R Language Server for R Component of GraalVM. | 95 | | `extension.graalvm.installRubyLanguageServer` | Install Ruby Language Server for Ruby Component of GraalVM. | 96 | | `extension.graalvm.setupProxy` | [Setup Proxy](#proxy-settings) for VS Code extensions. | 97 | | `extension.graalvm.openWindowsNITerminal` | Open Windows Terminal Preconfigured For [Native Image](#native-image). | 98 | | `extension.graalvm.heapReplay` | Replay Heap Recording. | 99 | 100 | ## Settings 101 | | Name | Description | Default Value / Possible Values | 102 | |---|---|---| 103 | | `graalvm.home` | Path to the active [GraalVM](#graalvm-wizard) installation. | "" | 104 | | `graalvm.installations` | Paths to [GraalVM](#graalvm-wizard) installations. | [] | 105 | | `graalvm.languageServer.start` | Start [GraalVM Language Server](#java-development). | "**none**", "single", "inProcess" | 106 | | `graalvm.languageServer.currentWorkDir` | Absolute path to the working directory of the [GraalVM Language Server](#java-development). | "" | 107 | | `graalvm.languageServer.delegateServers` | Comma-separated list of "language@[host:]port" where other language servers run. | "" | 108 | | `graalvm.languageServer.startRLanguageServer` | Start R Language Server. | false | 109 | | `graalvm.languageServer.startRubyLanguageServer` | Start Ruby Language Server. | false | 110 | | `graalvm.systemDetect` | Detect system [GraalVM](#graalvm-wizard) installations. | true | 111 | | `graalvm.gu.config` | Path to the custom [GraalVM](#graalvm-wizard) download configuration file. | "" | 112 | | `native.buildtools.config.windows` | Optional path to Windows Build Tools Configuration Script used for configuration of [Native Image](#native-image) Terminal for Windows. | "" | 113 | 114 | ## Contributing 115 | To submit pull requests to vscode-extensions, you need to sign the Oracle Contributor Agreement. 116 | 117 | Project members with write access to the repository will determine and assign an appropriate Assignee for the pull request. The assignee will work with the pull request owner to address any issues and then merge the pull request. 118 | 119 | ## Provide Feedback or Seek Help 120 | * [Request a feature](https://github.com/graalvm/vscode-extensions/issues/new?labels=enhancement) 121 | * [File a bug](https://github.com/graalvm/vscode-extensions/issues/new?labels=bug) 122 | 123 | ## Privacy Policy 124 | Read the [Oracle Privacy Policy](https://www.oracle.com/legal/privacy/privacy-policy.html) to learn more. -------------------------------------------------------------------------------- /graalvm/images/debugging_ni_vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/debugging_ni_vscode.png -------------------------------------------------------------------------------- /graalvm/images/graalvm-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/graalvm-logo.png -------------------------------------------------------------------------------- /graalvm/images/graalvm_install_actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/graalvm_install_actions.png -------------------------------------------------------------------------------- /graalvm/images/gutter-dark-green.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /graalvm/images/gutter-dark-red.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /graalvm/images/gutter-light-green.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /graalvm/images/gutter-light-red.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /graalvm/images/langs_vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/langs_vscode.png -------------------------------------------------------------------------------- /graalvm/images/proxyOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/proxyOn.png -------------------------------------------------------------------------------- /graalvm/images/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/run.png -------------------------------------------------------------------------------- /graalvm/images/supported_languages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/images/supported_languages.png -------------------------------------------------------------------------------- /graalvm/resources/graalvm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /graalvm/sl-language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ], 11 | "autoClosingPairs": [ 12 | { "open": "{", "close": "}" }, 13 | { "open": "[", "close": "]" }, 14 | { "open": "(", "close": ")" }, 15 | { "open": "\"", "close": "\"", "notIn": ["string"] }, 16 | { "open": "/*", "close": " */", "notIn": ["string"] } 17 | ], 18 | "surroundingPairs": [ 19 | ["{", "}"], 20 | ["[", "]"], 21 | ["(", ")"], 22 | ["\"", "\""] 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /graalvm/snippets/js-polyglot-snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Polyglot_eval": { 3 | "prefix": "Polyglot.eval", 4 | "body": [ 5 | "Polyglot.eval('${1|R,ruby,python|}', ${2:''})" 6 | ], 7 | "description": "Executes code in a foreign language identified by its ID" 8 | }, 9 | "Polyglot_evalFile": { 10 | "prefix": "Polyglot.evalFile", 11 | "body": [ 12 | "Polyglot.evalFile('${1|R,ruby,python|}', ${2:'path'})" 13 | ], 14 | "description": "Executes code in a foreign language from a file, identified by its language ID" 15 | }, 16 | "Polyglot_export": { 17 | "prefix": "Polyglot.export", 18 | "body": [ 19 | "Polyglot.export('${1:name}', ${2:value})" 20 | ], 21 | "description": "Exports a value with a given name to other languages" 22 | }, 23 | "Polyglot_import": { 24 | "prefix": "Polyglot.import", 25 | "body": [ 26 | "Polyglot.import('${1:name}')" 27 | ], 28 | "description": "Imports and returns a value with a given name exported by other languages" 29 | }, 30 | "Java_type": { 31 | "prefix": "Java.type", 32 | "body": [ 33 | "Java.type('${1:name}')" 34 | ], 35 | "description": "Returns a Java class object, given its name" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /graalvm/snippets/python-polyglot-snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Polyglot_eval": { 3 | "prefix": "polyglot.eval", 4 | "body": [ 5 | "polyglot.eval(language='${1|js,R,ruby|}', string=${2:''})" 6 | ], 7 | "description": "Executes code in a foreign language identified by its ID" 8 | }, 9 | "Polyglot_eval_file_by_id": { 10 | "prefix": "polyglot.eval", 11 | "body": [ 12 | "polyglot.eval(language='${1|js,R,ruby|}', path=${2:'file'})" 13 | ], 14 | "description": "Executes code in a foreign language from a file, identified by its ID" 15 | }, 16 | "Polyglot_eval_file": { 17 | "prefix": "polyglot.eval", 18 | "body": [ 19 | "polyglot.eval(path=${1:'file'})" 20 | ], 21 | "description": "Executes code in a foreign language from a file, automatically determining the language" 22 | }, 23 | "Polyglot_export_value": { 24 | "prefix": "polyglot.export_value", 25 | "body": [ 26 | "polyglot.export_value(${1:value}, name='${2}')" 27 | ], 28 | "description": "Exports a value with a given name to other languages" 29 | }, 30 | "Polyglot_import_value": { 31 | "prefix": "polyglot.import_value", 32 | "body": [ 33 | "polyglot.import_value('${1:name}')" 34 | ], 35 | "description": "Imports and returns a value with a given name exported by other languages" 36 | }, 37 | "Java_type": { 38 | "prefix": "java.type", 39 | "body": [ 40 | "java.type('${1:name}')" 41 | ], 42 | "description": "Returns a Java class object, given its name" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /graalvm/snippets/r-polyglot-snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Polyglot_eval": { 3 | "prefix": "eval.polyglot", 4 | "body": [ 5 | "eval.polyglot('${1|js,ruby,python|}', ${2|'',path='file'|})" 6 | ], 7 | "description": "Executes code in a foreign language identified by its ID" 8 | }, 9 | "Polyglot_export": { 10 | "prefix": "export", 11 | "body": [ 12 | "export('${1:name}', ${2:value})" 13 | ], 14 | "description": "Exports a value with a given name to other languages" 15 | }, 16 | "Polyglot_import": { 17 | "prefix": "import", 18 | "body": [ 19 | "import('${1:name}')" 20 | ], 21 | "description": "Imports and returns a value with a given name exported by other languages" 22 | }, 23 | "Java_type": { 24 | "prefix": "java.type", 25 | "body": [ 26 | "java.type('${1:name}')" 27 | ], 28 | "description": "Returns a Java class object, given its name" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /graalvm/snippets/ruby-polyglot-snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Polyglot_eval": { 3 | "prefix": "Polyglot.eval", 4 | "body": [ 5 | "Polyglot.eval('${1|js,R,python|}', ${2:''})" 6 | ], 7 | "description": "Executes code in a foreign language identified by its ID" 8 | }, 9 | "Polyglot_eval_file_by_id": { 10 | "prefix": "Polyglot.eval_file", 11 | "body": [ 12 | "Polyglot.eval_file('${1|js,R,python|}', ${2:'path'})" 13 | ], 14 | "description": "Executes code in a foreign language from a file, identified by its language ID" 15 | }, 16 | "Polyglot_eval_file": { 17 | "prefix": "Polyglot.eval_file", 18 | "body": [ 19 | "Polyglot.eval_file(${1:'path'})" 20 | ], 21 | "description": "Executes code in a foreign language from a file, automatically determining the language" 22 | }, 23 | "Polyglot_export": { 24 | "prefix": "Polyglot.export", 25 | "body": [ 26 | "Polyglot.export('${1:name}', ${2:value})" 27 | ], 28 | "description": "Exports a value with a given name to other languages" 29 | }, 30 | "Polyglot_export_method": { 31 | "prefix": "Polyglot.export_method", 32 | "body": [ 33 | "Polyglot.export_method('${1:name}')" 34 | ], 35 | "description": "Exports a method, defined in the top-level object, to other languages" 36 | }, 37 | "Polyglot_import": { 38 | "prefix": "Polyglot.import", 39 | "body": [ 40 | "Polyglot.import('${1:name}')" 41 | ], 42 | "description": "Imports and returns a value with a given name exported by other languages" 43 | }, 44 | "Polyglot_import_method": { 45 | "prefix": "Polyglot.import_method", 46 | "body": [ 47 | "Polyglot.import_method('${1:name}')" 48 | ], 49 | "description": "Imports a value, which should be IS_EXECUTABLE, with a given name, and defines it in the top-level object" 50 | }, 51 | "Java_type": { 52 | "prefix": "Java.type", 53 | "body": [ 54 | "Java.type('${1:name}')" 55 | ], 56 | "description": "Returns a Java class object, given its name" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /graalvm/snippets/sl-polyglot-snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Polyglot_eval": { 3 | "prefix": "eval", 4 | "body": [ 5 | "eval('${1|js,R,ruby,python|}', ${2:''})" 6 | ], 7 | "description": "Executes code in a foreign language identified by its ID" 8 | }, 9 | "Polyglot_import": { 10 | "prefix": "import", 11 | "body": [ 12 | "import('${1:name}')" 13 | ], 14 | "description": "Imports and returns a value with a given name exported by other languages" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /graalvm/src/extension.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import { toggleCodeCoverage, activeTextEditorChaged } from './graalVMCoverage'; 10 | import * as kubernetes from 'vscode-kubernetes-tools-api'; 11 | import * as debug from './graalVMDebug'; 12 | import { setupGraalVM, installGraalVM, addExistingGraalVM, installGraalVMComponent, uninstallGraalVMComponent, selectActiveGraalVM, findGraalVMs, InstallationNodeProvider, TreeItemComponent, Installation, removeGraalVMInstallation } from './graalVMInstall'; 13 | import { onClientNotification, startLanguageServer, stopLanguageServer } from './graalVMLanguageServer'; 14 | import { installRPackage, R_LANGUAGE_SERVER_PACKAGE_NAME } from './graalVMR'; 15 | import { installRubyGem, RUBY_LANGUAGE_SERVER_GEM_NAME } from './graalVMRuby'; 16 | import * as nativeImage from './graalVMNativeImage'; 17 | import { getGVMHome, setupProxy, configureGraalVMHome } from './graalVMConfiguration'; 18 | import * as gds from './gdsUtils'; 19 | 20 | export let extContext: vscode.ExtensionContext; 21 | export function activate(context: vscode.ExtensionContext) { 22 | extContext = context; 23 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.selectGraalVMHome', async (installation?: string | Installation, nonInteractive?: boolean) => { 24 | await selectActiveGraalVM(installation instanceof Installation ? installation.home : installation, nonInteractive); 25 | })); 26 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installGraalVM', () => { 27 | installGraalVM(); 28 | })); 29 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.addExistingGraalVM', () => { 30 | addExistingGraalVM(); 31 | })); 32 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.findGraalVMs', async () => { 33 | const graalVMHome = getGVMHome(); 34 | return (await findGraalVMs()).map(item => ({name: item.name, path: item.path, active: item.path === graalVMHome})); 35 | })); 36 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installGraalVMComponent', (component: string | TreeItemComponent | undefined, homeFolder?: string) => { 37 | installGraalVMComponent(component, homeFolder); 38 | })); 39 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.uninstallGraalVMComponent', (component: string | TreeItemComponent | undefined, homeFolder?: string) => { 40 | uninstallGraalVMComponent(component, homeFolder); 41 | })); 42 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.addNativeImageToPOM', () => { 43 | nativeImage.addNativeImageToPOM(); 44 | })); 45 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.attachNativeImageAgent', async (): Promise => { 46 | return await nativeImage.attachNativeImageAgent(); 47 | })); 48 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.toggleCodeCoverage', () => { 49 | toggleCodeCoverage(); 50 | })); 51 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installRLanguageServer', () => { 52 | if(!installRPackage(R_LANGUAGE_SERVER_PACKAGE_NAME)){ 53 | vscode.window.showErrorMessage("R isn't present in GraalVM Installation."); 54 | } 55 | })); 56 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installRubyLanguageServer', () => { 57 | if(!installRubyGem(RUBY_LANGUAGE_SERVER_GEM_NAME)){ 58 | vscode.window.showErrorMessage("Ruby isn't present in GraalVM Installation."); 59 | } 60 | })); 61 | context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(e => { 62 | if (e) { 63 | activeTextEditorChaged(e); 64 | } 65 | })); 66 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.setupProxy' , () => { 67 | setupProxy(); 68 | })); 69 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.removeInstallation', (path?: string | Installation) => { 70 | removeGraalVMInstallation(path instanceof Installation ? path.home : path); 71 | })); 72 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.gds.showConfiguration', () => { 73 | gds.showConfiguration(); 74 | })); 75 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.createWindowsNITerminal', (options: vscode.TerminalOptions): Promise => { 76 | return nativeImage.createWindowsNITerminal(options); 77 | })); 78 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.openWindowsNITerminal', () => { 79 | nativeImage.openWindowsNITerminal(); 80 | })); 81 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.showDocsNativeImage', (...params: any[]) => { 82 | nativeImage.showDocumentation(params); 83 | })); 84 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.configureSettingNativeImage', (...params: any[]) => { 85 | nativeImage.configureSetting(context, params); 86 | })); 87 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.openConfigNativeImage', () => { 88 | nativeImage.openConfiguration(); 89 | })); 90 | nativeImage.initializeConfiguration().then(initialized => { 91 | if (initialized) { 92 | context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java+', nativeImage.configurationProvider)); 93 | context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java8+', nativeImage.configurationProvider)); 94 | context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java', nativeImage.configurationProvider)); 95 | vscode.commands.executeCommand('setContext', 'nativeImageInitialized', true); 96 | } 97 | }); 98 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.debugKubernetes', debug.attachToKubernetes)); 99 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.heapReplay', debug.heapReplay)); 100 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installNBJava', () => { 101 | vscode.commands.executeCommand('workbench.extensions.installExtension', 'asf.apache-netbeans-java'); 102 | nativeImage.setFeatureSet(-2); 103 | })); 104 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installRHJava', () => { 105 | vscode.commands.executeCommand('workbench.extensions.installExtension', 'redhat.java'); 106 | nativeImage.setFeatureSet(-2); 107 | })); 108 | context.subscriptions.push(vscode.window.registerTreeDataProvider('ni-control-panel', nativeImage.nodeProvider)); 109 | context.subscriptions.push( 110 | vscode.commands.registerCommand( 111 | 'extension.graalvm.debugPod', 112 | (kubectl: kubernetes.KubectlV1, podName: string, namespace?: string) => { 113 | debug.attachToPod(kubectl, podName, namespace); 114 | }) 115 | ); 116 | 117 | const nodeProvider = new InstallationNodeProvider(); 118 | context.subscriptions.push(vscode.window.registerTreeDataProvider('graalvm-installations', nodeProvider)); 119 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.refreshInstallations', () => nodeProvider.refresh())); 120 | const configurationProvider = new debug.GraalVMConfigurationProvider(); 121 | context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('graalvm', configurationProvider)); 122 | context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('node', configurationProvider)); 123 | context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('graalvm', new debug.GraalVMDebugAdapterDescriptorFactory())); 124 | context.subscriptions.push(vscode.debug.registerDebugAdapterTrackerFactory('graalvm', new debug.GraalVMDebugAdapterTracker())); 125 | context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(e => { 126 | if (e.affectsConfiguration('graalvm.home')) { 127 | vscode.commands.executeCommand('extension.graalvm.refreshInstallations'); 128 | const graalVMHome = getGVMHome(); 129 | nativeImage.initializeGraalVM(graalVMHome); 130 | if (!graalVMHome) { 131 | setupGraalVM(); 132 | } 133 | stopLanguageServer().then(() => startLanguageServer(getGVMHome())); 134 | } else if (e.affectsConfiguration('graalvm.installations') || e.affectsConfiguration('graalvm.systemDetect')) { 135 | vscode.commands.executeCommand('extension.graalvm.refreshInstallations'); 136 | } else if (e.affectsConfiguration('graalvm.languageServer.currentWorkDir') || e.affectsConfiguration('graalvm.languageServer.start')) { 137 | stopLanguageServer().then(() => startLanguageServer(getGVMHome())); 138 | } 139 | })); 140 | context.subscriptions.push(vscode.extensions.onDidChange(() => { 141 | const graalVMHome = getGVMHome(); 142 | nativeImage.initializeGraalVM(graalVMHome); 143 | const netbeansExt = vscode.extensions.getExtension('asf.apache-netbeans-java'); 144 | if (netbeansExt) { 145 | configureGraalVMHome(graalVMHome, true); 146 | } 147 | })); 148 | const graalVMHome = getGVMHome(); 149 | if (!graalVMHome) { 150 | setupGraalVM(); 151 | } else { 152 | selectActiveGraalVM(graalVMHome, true).then(() => startLanguageServer(graalVMHome)); 153 | } 154 | nativeImage.initialize(context); 155 | 156 | context.subscriptions.push(vscode.commands.registerCommand('extension.graalvm.installVisualVMIntegration', async () => { 157 | const VISUALVM_EXTENSION_ID = 'oracle-labs-graalvm.visualvm-vscode'; 158 | const VISUALVM_EXTENSION_NAME = 'VisualVM for VS Code'; 159 | if (vscode.extensions.getExtension(VISUALVM_EXTENSION_ID)) { 160 | await vscode.window.showInformationMessage(`${VISUALVM_EXTENSION_NAME} extension already installed.`); 161 | } else { 162 | try { 163 | await vscode.commands.executeCommand('workbench.extensions.installExtension', VISUALVM_EXTENSION_ID); 164 | } catch (err) { 165 | await vscode.window.showErrorMessage(`Failed to install ${VISUALVM_EXTENSION_NAME} extension: ${err}`); 166 | } 167 | } 168 | })); 169 | 170 | vscode.window.setStatusBarMessage('GraalVM extension activated', 3000); 171 | 172 | // Public API 173 | return { 174 | onClientNotification: onClientNotification, 175 | }; 176 | } 177 | 178 | export async function deactivate() { 179 | return await stopLanguageServer(); 180 | } 181 | -------------------------------------------------------------------------------- /graalvm/src/graalVMCoverage.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import { pathToFileURL } from 'url'; 10 | import { extContext } from './extension'; 11 | 12 | const coverageOn = new Set(); 13 | let coveredDecoration: vscode.TextEditorDecorationType; 14 | let uncoveredDecoration: vscode.TextEditorDecorationType; 15 | 16 | export async function toggleCodeCoverage() { 17 | const editor = vscode.window.activeTextEditor; 18 | if (editor) { 19 | if (!uncoveredDecoration) { 20 | uncoveredDecoration = vscode.window.createTextEditorDecorationType({ 21 | dark: { 22 | gutterIconPath: extContext.asAbsolutePath('images/gutter-dark-red.svg'), 23 | gutterIconSize: 'contain', 24 | overviewRulerColor: '#630417', 25 | }, 26 | light: { 27 | gutterIconPath: extContext.asAbsolutePath('images/gutter-light-red.svg'), 28 | gutterIconSize: 'contain', 29 | overviewRulerColor: '#f29494', 30 | }, 31 | overviewRulerLane: vscode.OverviewRulerLane.Right, 32 | }); 33 | } 34 | if (!coveredDecoration) { 35 | coveredDecoration = vscode.window.createTextEditorDecorationType({ 36 | dark: { 37 | gutterIconPath: extContext.asAbsolutePath('images/gutter-dark-green.svg'), 38 | gutterIconSize: 'contain', 39 | overviewRulerColor: '#144014', 40 | }, 41 | light: { 42 | gutterIconPath: extContext.asAbsolutePath('images/gutter-light-green.svg'), 43 | gutterIconSize: 'contain', 44 | overviewRulerColor: '#a6e3a6', 45 | }, 46 | overviewRulerLane: vscode.OverviewRulerLane.Right, 47 | }); 48 | } 49 | const id = (editor as any).id; 50 | if (coverageOn.has(id)) { 51 | coverageOn.delete(id); 52 | editor.setDecorations(coveredDecoration, []); 53 | editor.setDecorations(uncoveredDecoration, []); 54 | } else { 55 | if (await showCoverage(editor)) { 56 | coverageOn.add(id); 57 | } else { 58 | vscode.window.setStatusBarMessage('No coverage data available.', 3000); 59 | } 60 | } 61 | } 62 | } 63 | 64 | export async function activeTextEditorChaged(editor: vscode.TextEditor) { 65 | const id = (editor as any).id; 66 | if (coverageOn.has(id)) { 67 | if (await showCoverage(editor)) { 68 | coverageOn.add(id); 69 | } else { 70 | coverageOn.delete(id); 71 | vscode.window.setStatusBarMessage('No coverage data available.', 3000); 72 | } 73 | } 74 | } 75 | 76 | async function showCoverage(editor: vscode.TextEditor): Promise { 77 | return new Promise((resolve) => { 78 | vscode.commands.getCommands().then((commands: string[]) => { 79 | if (commands.includes('get_coverage')) { 80 | vscode.commands.executeCommand('get_coverage', pathToFileURL(editor.document.uri.fsPath)).then((value) => { 81 | if (value) { 82 | const coverage = value as {covered: vscode.Range[]; uncovered: vscode.Range[]}; 83 | editor.setDecorations(coveredDecoration, coverage.covered); 84 | editor.setDecorations(uncoveredDecoration, coverage.uncovered); 85 | resolve(true); 86 | } else { 87 | resolve(false); 88 | } 89 | }); 90 | } else { 91 | resolve(false); 92 | } 93 | }); 94 | }); 95 | } -------------------------------------------------------------------------------- /graalvm/src/graalVMDebugAdapter.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import { ChromeDebugAdapter, ChromeDebugSession, Crdp, ErrorWithMessage, logger } from 'vscode-chrome-debug-core'; 9 | import { DebugProtocol } from 'vscode-debugprotocol'; 10 | import { OutputEvent } from 'vscode-debugadapter'; 11 | 12 | import * as path from 'path'; 13 | import * as cp from 'child_process'; 14 | import * as os from 'os'; 15 | 16 | import { ILaunchRequestArguments, IAttachRequestArguments } from './graalVMDebugInterfaces'; 17 | 18 | interface DAPEnv { 19 | [key: string]: string | null; 20 | }; 21 | 22 | export class GraalVMDebugAdapter extends ChromeDebugAdapter { 23 | private static TIMEOUT = 5000; 24 | 25 | private _childProcessId: number = 0; 26 | private _supportsRunInTerminalRequest: boolean | undefined; 27 | private _lastEarlyNodeMsgSeen: boolean | undefined; 28 | private _captureStdOutput: boolean | undefined; 29 | private _killChildProcess: boolean = true; 30 | 31 | private convertProcessEnvToDAPEnv(pEnv : NodeJS.ProcessEnv) : DAPEnv { 32 | let dEnv: DAPEnv = {}; 33 | for (let [ek, ev] of Object.entries(pEnv)) { 34 | if (ev) { 35 | dEnv[ek] = ev; 36 | } else { 37 | dEnv[ek] = null; 38 | } 39 | } 40 | return dEnv; 41 | } 42 | 43 | public initialize(args: DebugProtocol.InitializeRequestArguments): DebugProtocol.Capabilities { 44 | this._supportsRunInTerminalRequest = args.supportsRunInTerminalRequest; 45 | const capabilities = super.initialize(args); 46 | return capabilities; 47 | } 48 | 49 | public async launch(args: ILaunchRequestArguments): Promise { 50 | if (!args.breakOnLoadStrategy) { 51 | args.breakOnLoadStrategy = 'regex'; 52 | } 53 | if (args.console && args.console !== 'internalConsole' && typeof args._suppressConsoleOutput === 'undefined') { 54 | args._suppressConsoleOutput = true; 55 | } 56 | 57 | await super.launch(args); 58 | 59 | if (args.graalVMLaunchInfo.args.find(arg => arg.startsWith('--lsp'))) { 60 | this._killChildProcess = false; 61 | } 62 | 63 | this._captureStdOutput = args.outputCapture === 'std'; 64 | 65 | if (args.console === 'integratedTerminal' && this._supportsRunInTerminalRequest) { 66 | const termArgs: DebugProtocol.RunInTerminalRequestArguments = { 67 | kind: args.console === 'integratedTerminal' ? 'integrated' : 'external', 68 | title: 'GraalVM Debug Console', 69 | cwd: args.graalVMLaunchInfo.cwd, 70 | env: this.convertProcessEnvToDAPEnv(args.graalVMLaunchInfo.env), 71 | args: [args.graalVMLaunchInfo.exec].concat(args.graalVMLaunchInfo.args || []) 72 | }; 73 | await this.launchInTerminal(termArgs); 74 | if (args.noDebug) { 75 | this.terminateSession('cannot track process'); 76 | } 77 | } else if (!args.console || args.console === 'internalConsole') { 78 | await this.launchInInternalConsole(args.graalVMLaunchInfo.exec, args.graalVMLaunchInfo.args, args.graalVMLaunchInfo.env, args.graalVMLaunchInfo.cwd); 79 | } else { 80 | throw new ErrorWithMessage({ 81 | id: 2028, 82 | format: "Unknown console type '{consoleType}'.", 83 | variables: { consoleType: args.console } 84 | }); 85 | } 86 | 87 | if (!this._killChildProcess && this._childProcessId > 0) { 88 | this._session.sendEvent(new OutputEvent('childProcessID', 'telemetry', {'pid': this._childProcessId})); 89 | } 90 | 91 | if (!args.noDebug) { 92 | await this.doAttach(args.graalVMLaunchInfo.port, undefined, args.address, args.timeout, undefined, args.extraCRDPChannelPort); 93 | this._session.sendEvent(new OutputEvent('Debugger attached.\n', 'stderr')); 94 | } 95 | } 96 | 97 | public async attach(args: IAttachRequestArguments): Promise { 98 | try { 99 | if (!args.breakOnLoadStrategy) { 100 | args.breakOnLoadStrategy = 'regex'; 101 | } 102 | if (typeof args.enableSourceMapCaching !== 'boolean') { 103 | args.enableSourceMapCaching = true; 104 | } 105 | return super.attach(args); 106 | } catch (err: any) { 107 | if (err.format && err.format.indexOf('Cannot connect to runtime process') >= 0) { 108 | err.format = 'Ensure GraalVM was launched with --inspect. ' + err.format; 109 | } 110 | throw err; 111 | } 112 | } 113 | 114 | public async terminateSession(reason: string): Promise { 115 | this.killChildProcess(); 116 | return super.terminateSession(reason); 117 | } 118 | 119 | private killChildProcess(): void { 120 | if (this._killChildProcess && this._childProcessId > 0 && !this._attachMode) { 121 | if (process.platform === 'win32') { 122 | try { 123 | cp.execSync(`${path.join(process.env['WINDIR'] || 'C:\\Windows', 'System32', 'taskkill.exe')} /f /t /pid ${this._childProcessId}`); 124 | } catch (e) {} 125 | } else { 126 | const groupPID = -this._childProcessId; 127 | try { 128 | process.kill(groupPID, 'SIGKILL'); 129 | } catch (ex: unknown) { 130 | const e = ex as Error; 131 | if (e.message === 'kill ESRCH') { 132 | try { 133 | process.kill(this._childProcessId, 'SIGKILL'); 134 | } catch (e) {} 135 | } 136 | } 137 | } 138 | this._childProcessId = 0; 139 | } 140 | } 141 | 142 | private launchInTerminal(termArgs: DebugProtocol.RunInTerminalRequestArguments): Promise { 143 | return new Promise((resolve, reject) => { 144 | this._session.sendRequest('runInTerminal', termArgs, GraalVMDebugAdapter.TIMEOUT, response => { 145 | if (response.success) { 146 | resolve(); 147 | } else { 148 | reject(new ErrorWithMessage({ 149 | id: 2011, 150 | format: 'Cannot launch debug target in terminal ({_error}).', 151 | variables: { _error: response.message || '' } 152 | })); 153 | this.terminateSession('terminal error: ' + response.message); 154 | } 155 | }); 156 | }); 157 | } 158 | 159 | private launchInInternalConsole(runtimeExecutable: string, launchArgs: string[], env: NodeJS.ProcessEnv, cwd?: string): Promise { 160 | const spawnOpts: cp.SpawnOptions = { cwd, env, detached: true }; 161 | this.logLaunchCommand(runtimeExecutable, launchArgs); 162 | const childProcess = cp.spawn(runtimeExecutable, launchArgs, spawnOpts); 163 | return new Promise((resolve, reject) => { 164 | this._childProcessId = childProcess.pid; 165 | childProcess.on('error', (error) => { 166 | reject(new ErrorWithMessage({ 167 | id: 2017, 168 | format: 'Cannot launch debug target ({_error}).', 169 | variables: { _error : error.toString() }, 170 | showUser: true, 171 | sendTelemetry: true 172 | })); 173 | const msg = `Child process error: ${error}`; 174 | logger.error(msg); 175 | this.terminateSession(msg); 176 | }); 177 | childProcess.on('exit', () => { 178 | const msg = 'Target exited'; 179 | logger.log(msg); 180 | this.terminateSession(msg); 181 | }); 182 | childProcess.on('close', () => { 183 | const msg = 'Target closed'; 184 | logger.log(msg); 185 | this.terminateSession(msg); 186 | }); 187 | const noDebugMode = (this._launchAttachArgs).noDebug; 188 | if (childProcess.stdout) { 189 | childProcess.stdout.on('data', (data: string) => { 190 | if ((noDebugMode || this._captureStdOutput) && !this._launchAttachArgs._suppressConsoleOutput) { 191 | let msg = data.toString(); 192 | this._session.sendEvent(new OutputEvent(msg, 'stdout')); 193 | } 194 | }); 195 | } 196 | if (childProcess.stderr) { 197 | childProcess.stderr.on('data', (data: string) => { 198 | let msg = data.toString(); 199 | if (!this._lastEarlyNodeMsgSeen && !noDebugMode) { 200 | msg = msg.replace(/^\s*To start debugging, open the following URL in Chrome:\s*$/m, ''); 201 | let regExp = /^\s*chrome-devtools:\/\/devtools\/bundled\/js_app\.html\?ws=\S*\s*$/m; 202 | if (msg.match(regExp)) { 203 | msg = msg.replace(regExp, ''); 204 | this._lastEarlyNodeMsgSeen = true; 205 | } 206 | } 207 | if ((noDebugMode || this._captureStdOutput) && !this._launchAttachArgs._suppressConsoleOutput) { 208 | this._session.sendEvent(new OutputEvent(msg, 'stderr')); 209 | } 210 | }); 211 | } 212 | resolve(); 213 | }); 214 | } 215 | 216 | protected onConsoleAPICalled(params: Crdp.Runtime.ConsoleAPICalledEvent): void { 217 | this._lastEarlyNodeMsgSeen = true; 218 | if (!this._captureStdOutput) { 219 | super.onConsoleAPICalled(params); 220 | } 221 | } 222 | 223 | private logLaunchCommand(executable: string, args: string[]) { 224 | let cli = executable + ' '; 225 | for (let a of args) { 226 | if (a.indexOf(' ') >= 0) { 227 | cli += '\'' + a + '\''; 228 | } else { 229 | cli += a; 230 | } 231 | cli += ' '; 232 | } 233 | logger.warn(cli); 234 | } 235 | } 236 | 237 | ChromeDebugSession.run(ChromeDebugSession.getSession({ 238 | adapter: GraalVMDebugAdapter, 239 | extensionName: 'graalvm', 240 | logFilePath: path.resolve(os.tmpdir(), 'vscode-graalvm-debug.txt'), 241 | })); 242 | -------------------------------------------------------------------------------- /graalvm/src/graalVMDebugInterfaces.d.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as Core from 'vscode-chrome-debug-core'; 9 | 10 | type ConsoleType = 'internalConsole' | 'integratedTerminal'; 11 | type OutputCaptureType = 'console' | 'std'; 12 | type Protocol = 'debugAdapter' | 'chromeDevTools'; 13 | 14 | export interface ICommonRequestArgs extends Core.ICommonRequestArgs { 15 | /** TCP/IP address of process to be debugged. Default is 'localhost'. */ 16 | address?: string; 17 | /** Optional timeout to connect */ 18 | timeout?: number; 19 | /** Protocol used to connect the debuggee */ 20 | protocol?: Protocol; 21 | } 22 | 23 | export interface ILaunchRequestArguments extends Core.ILaunchRequestArgs, ICommonRequestArgs { 24 | /** An absolute path to the program to debug. */ 25 | program: string; 26 | /** Optional arguments passed to the debuggee. */ 27 | args?: string[]; 28 | /** Launch the debuggee in this working directory (specified as an absolute path). If omitted the debuggee is lauched in the workspace directory. */ 29 | cwd: string; 30 | /** Customize evironment variables. To set a variable specify: "NewVar" : "New Value", to delete one specify: "EnvVar" : null */ 31 | env: object; 32 | /** Absolute path to the runtime executable to be used. */ 33 | runtimeExecutable?: string; 34 | /** Optional arguments passed to the runtime executable. */ 35 | runtimeArgs?: string[]; 36 | /** Where to launch the debug target. */ 37 | console?: ConsoleType; 38 | /** Manually selected debugging port */ 39 | port?: number; 40 | /** Debugger-specific options passed to the debuggee. */ 41 | debugOptions: object; 42 | /** Source of the debug output */ 43 | outputCapture?: OutputCaptureType; 44 | /** GraalVM launch info. */ 45 | graalVMLaunchInfo: IGraalVMLaunchInfo; 46 | } 47 | 48 | export interface IAttachRequestArguments extends Core.IAttachRequestArgs, ICommonRequestArgs { 49 | /** Node's root directory. */ 50 | remoteRoot?: string; 51 | /** VS Code's root directory. */ 52 | localRoot?: string; 53 | } 54 | 55 | export interface IGraalVMLaunchInfo { 56 | /** Absolute path to the runtime executable. */ 57 | exec: string; 58 | /** Arguments passed to the runtime executable. */ 59 | args: string[]; 60 | /** Launch the runtime executable in this working directory (specified as an absolute path). */ 61 | cwd: string; 62 | /** Customize evironment variables. */ 63 | env: NodeJS.ProcessEnv; 64 | /** Selected debugging port. */ 65 | port: number; 66 | } 67 | -------------------------------------------------------------------------------- /graalvm/src/graalVMLanguageServer.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as cp from 'child_process'; 10 | import * as utils from './utils'; 11 | import * as net from 'net'; 12 | import { GenericNotificationHandler, LanguageClient, LanguageClientOptions, StreamInfo } from 'vscode-languageclient/node'; 13 | import { getGVMConfig } from './graalVMConfiguration'; 14 | 15 | export const LSPORT: number = 8123; 16 | const POLYGLOT: string = 'polyglot'; 17 | const delegateLanguageServers: Set<() => Thenable> = new Set(); 18 | 19 | let languageClient: Promise | undefined; 20 | let languageServerPID: number = 0; 21 | let hasR: boolean | undefined; 22 | 23 | export function registerLanguageServer(server: (() => Thenable)): void { 24 | delegateLanguageServers.add(server); 25 | } 26 | 27 | export function startLanguageServer(graalVMHome?: string) { 28 | if (!graalVMHome) { 29 | return; 30 | } 31 | const languageServerStart = getGVMConfig().get('languageServer.start') as 'none' | 'single' | 'inProcess'; 32 | if (languageServerStart === 'single' || delegateLanguageServers.size > 0) { 33 | const re = utils.findExecutable(POLYGLOT, graalVMHome); 34 | if (re) { 35 | let serverWorkDir: string | undefined = getGVMConfig().get('languageServer.currentWorkDir') as string; 36 | if (!serverWorkDir) { 37 | serverWorkDir = vscode.workspace.rootPath; 38 | } 39 | if (serverWorkDir) { 40 | connectToLanguageServer(() => new Promise((resolve, reject) => { 41 | lspArgs().then(args => { 42 | const lspArg = args.find(arg => arg.startsWith('--lsp=')); 43 | const lsPort = lspArg ? parseInt(lspArg.substring(6)) : LSPORT; 44 | const serverProcess = cp.spawn(re, args.concat(['--experimental-options', '--shell']), { cwd: serverWorkDir }); 45 | if (!serverProcess || !serverProcess.pid) { 46 | reject(`Launching server using command ${re} failed.`); 47 | } else { 48 | languageServerPID = serverProcess.pid; 49 | serverProcess.on('close', code => { 50 | if (code) { 51 | reject(`Server exited with exit code: ${code}`); 52 | } 53 | }); 54 | serverProcess.stdout.once('data', () => { 55 | const socket = new net.Socket(); 56 | socket.once('error', (e) => { 57 | reject(e); 58 | }); 59 | setTimeout(() => { 60 | socket.connect(lsPort, '127.0.0.1', () => { 61 | resolve({ 62 | reader: socket, 63 | writer: socket 64 | }); 65 | }); 66 | }, 1000); 67 | }); 68 | } 69 | }); 70 | })); 71 | } 72 | } else { 73 | vscode.window.showErrorMessage('Cannot find runtime ' + POLYGLOT + ' within your GraalVM installation.'); 74 | } 75 | } 76 | } 77 | 78 | export function connectToLanguageServer(connection: () => Promise) { 79 | const clientOptions: LanguageClientOptions = { 80 | documentSelector: [ 81 | { scheme: 'file', language: 'javascript' }, 82 | { scheme: 'file', language: 'sl' }, 83 | { scheme: 'file', language: 'python' }, 84 | { scheme: 'file', language: 'r' }, 85 | { scheme: 'file', language: 'ruby' } 86 | ] 87 | }; 88 | 89 | languageClient = new Promise((resolve) => { 90 | let client = new LanguageClient('GraalVMLanguageServer', 'GraalVM Language Client', connection, clientOptions); 91 | let prepareStatus = vscode.window.setStatusBarMessage("Graal Language Client: Connecting to GraalLS"); 92 | client.start().then(() => { 93 | prepareStatus.dispose(); 94 | vscode.window.setStatusBarMessage('GraalLS is ready.', 3000); 95 | resolve(client); 96 | }).catch(() => { 97 | prepareStatus.dispose(); 98 | vscode.window.setStatusBarMessage('GraalLS failed to initialize.', 3000); 99 | resolve(client); 100 | }); 101 | }); 102 | } 103 | 104 | export function stopLanguageServer(): Thenable { 105 | if (languageClient) { 106 | let terminate = () => { 107 | languageClient = undefined; 108 | if (languageServerPID > 0) { 109 | terminateLanguageServer(); 110 | } 111 | }; 112 | return languageClient.then((client) => client.stop().then(terminate, terminate)); 113 | } 114 | if (languageServerPID > 0) { 115 | terminateLanguageServer(); 116 | } 117 | return Promise.resolve(); 118 | } 119 | 120 | export async function lspArgs(): Promise { 121 | const port = utils.random(3000, 50000); 122 | let delegateServers: string | undefined = getGVMConfig().get('languageServer.delegateServers') as string; 123 | const s = Array.from(delegateLanguageServers).map(server => server()); 124 | const r = await hasRSource(); 125 | return Promise.all(s).then((servers) => { 126 | let args = r ? ['--jvm', `--lsp=${port}`] : [`--lsp=${port}`]; 127 | delegateServers = delegateServers ? delegateServers.concat(',', servers.join()) : servers.join(); 128 | if (delegateServers) { 129 | args = args.concat('--lsp.Delegates=' + delegateServers); 130 | } 131 | return args; 132 | }); 133 | } 134 | 135 | export function setLSPID(pid: number) { 136 | languageServerPID = pid; 137 | } 138 | 139 | export function hasLSClient(): boolean { 140 | return languageClient !== undefined; 141 | } 142 | 143 | async function hasRSource(): Promise { 144 | if (hasR === undefined) { 145 | const uris: vscode.Uri[] = await vscode.workspace.findFiles('*.{r,R}', undefined, 1); 146 | hasR = uris.length > 0; 147 | if (!hasR) { 148 | const fsWatcher = vscode.workspace.createFileSystemWatcher('*.{r,R}', false, true, true); 149 | fsWatcher.onDidCreate(_uri => { 150 | hasR = true; 151 | fsWatcher.dispose(); 152 | }); 153 | } 154 | } 155 | return hasR; 156 | } 157 | 158 | export async function onClientNotification(method: string, handler: GenericNotificationHandler): Promise { 159 | if (languageClient) { 160 | let isSuccessful = false; 161 | await languageClient.then((client) => client.onNotification(method, handler)).then(() => isSuccessful = true); 162 | return isSuccessful; 163 | } else { 164 | return false; 165 | } 166 | } 167 | 168 | function terminateLanguageServer() { 169 | utils.killProcess(languageServerPID); 170 | languageServerPID = 0; 171 | } 172 | -------------------------------------------------------------------------------- /graalvm/src/graalVMLicenseCheck.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as path from 'path'; 10 | import * as fs from 'fs'; 11 | import * as mustache from 'mustache'; 12 | import { extContext } from './extension'; 13 | 14 | export class LicenseCheckPanel { 15 | 16 | public static readonly viewType: string = 'graalVMLicenseCheck'; 17 | 18 | private static readonly webviewsFolder: string = 'webviews'; 19 | private static readonly userAcceptedLicenses: string = 'userAcceptedLicenses'; 20 | 21 | private readonly _panel: vscode.WebviewPanel; 22 | private _disposables: vscode.Disposable[] = []; 23 | 24 | public static show(licenseLabel: string, license: string): Promise { 25 | const userAcceptedLicenses = JSON.parse(extContext.globalState.get(LicenseCheckPanel.userAcceptedLicenses) || '{}'); 26 | return new Promise(resolve => { 27 | new LicenseCheckPanel(extContext.extensionPath, licenseLabel, license, userAcceptedLicenses.userEmail, (message: any) => { 28 | if (message?.command === 'accepted') { 29 | if (message.email) { 30 | userAcceptedLicenses.userEmail = message.email; 31 | extContext.globalState.update(LicenseCheckPanel.userAcceptedLicenses, JSON.stringify(userAcceptedLicenses)); 32 | } 33 | resolve(userAcceptedLicenses.userEmail); 34 | } else { 35 | resolve(undefined); 36 | } 37 | }); 38 | }); 39 | } 40 | 41 | private constructor(extensionPath: string, licenseLabel: string, license: string, userEmail: string, messageHandler: (message: any) => any) { 42 | this._panel = vscode.window.createWebviewPanel(LicenseCheckPanel.viewType, licenseLabel, 43 | { viewColumn: vscode.ViewColumn.One, preserveFocus: true }, 44 | { 45 | enableScripts: true, 46 | localResourceRoots: [vscode.Uri.file(path.join(extensionPath, LicenseCheckPanel.webviewsFolder))] 47 | } 48 | ); 49 | this._panel.iconPath = { 50 | light: vscode.Uri.file(path.join(extensionPath, LicenseCheckPanel.webviewsFolder, 'icons', 'law_light.png')), 51 | dark: vscode.Uri.file(path.join(extensionPath, LicenseCheckPanel.webviewsFolder, 'icons', 'law_dark.png')) 52 | }; 53 | 54 | // Set the webview's html content 55 | this.setHtml(extensionPath, license, userEmail || ''); 56 | 57 | let result: any; 58 | 59 | // Listen for when the panel is disposed 60 | // This happens when the user closes the panel or when the panel is closed programatically 61 | this._panel.onDidDispose( 62 | () => { 63 | this.dispose(); 64 | messageHandler(result); 65 | }, 66 | null, 67 | this._disposables); 68 | 69 | // Update the content based on view changes 70 | this._panel.onDidChangeViewState( 71 | () => { 72 | if (this._panel.visible) { 73 | this.setHtml(extensionPath, license, userEmail || ''); 74 | } 75 | }, 76 | null, 77 | this._disposables 78 | ); 79 | 80 | // Handle messages from the webview 81 | this._panel.webview.onDidReceiveMessage( 82 | (message: any) => { 83 | result = message; 84 | this.dispose(); 85 | }, 86 | undefined, 87 | this._disposables 88 | ); 89 | } 90 | 91 | private setHtml(extensionPath: string, license: string, email: string) { 92 | const templatePath = path.join(extensionPath, LicenseCheckPanel.webviewsFolder, 'licenseCheck.html'); 93 | this._panel.webview.html = mustache.render(fs.readFileSync(templatePath).toString(), { 94 | cspSource: this._panel.webview.cspSource, 95 | email, 96 | license: license, 97 | cssUri: this._panel.webview.asWebviewUri(vscode.Uri.file(path.join(extensionPath, LicenseCheckPanel.webviewsFolder, 'styles', 'licenseCheck.css'))), 98 | jsUri: this._panel.webview.asWebviewUri(vscode.Uri.file(path.join(extensionPath, LicenseCheckPanel.webviewsFolder, 'scripts', 'licenseCheck.js'))) 99 | }); 100 | } 101 | 102 | public dispose() { 103 | // Clean up our resources 104 | this._panel.dispose(); 105 | while (this._disposables.length) { 106 | const x = this._disposables.pop(); 107 | if (x) { 108 | x.dispose(); 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /graalvm/src/graalVMPython.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as utils from './utils'; 9 | import { ConfigurationPickItem, getConf, setConf } from './graalVMConfiguration'; 10 | 11 | export function getPythonConfigurations(): ConfigurationPickItem[] { 12 | const ret: ConfigurationPickItem[] = []; 13 | ret.push(new ConfigurationPickItem( 14 | 'Set as Python runtime', 15 | '(python.pythonPath)', 16 | graalVMHome => utils.findExecutables(['graalpy', 'graalpython'], graalVMHome) !== undefined && utils.checkRecommendedExtension('ms-python.python', 'Python Language'), 17 | graalVMHome => utils.findExecutables(['graalpy', 'graalpython'], graalVMHome) === getConf('python').get('pythonPath'), 18 | async graalVMHome => { 19 | const executable = utils.findExecutables(['graalpy', 'graalpython'], graalVMHome); 20 | if (executable) { 21 | return setConfig('pythonPath', executable); 22 | } 23 | }, 24 | async _graalVMHome => setConfig('pythonPath', undefined)) 25 | ); 26 | return ret; 27 | } 28 | 29 | function setConfig(section: string, path?: string) { 30 | const config = getConf('python'); 31 | const term = config.inspect(section); 32 | if (term) { 33 | setConf(config, section, path); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /graalvm/src/graalVMR.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as cp from 'child_process'; 10 | import * as net from 'net'; 11 | import { TextEncoder } from 'util'; 12 | import * as utils from './utils'; 13 | import { registerLanguageServer } from './graalVMLanguageServer'; 14 | import { ConfigurationPickItem, getConf, getGVMConfig, getGVMHome, setConf } from './graalVMConfiguration'; 15 | 16 | export const R_LANGUAGE_SERVER_PACKAGE_NAME: string = 'languageserver'; 17 | const INSTALL_R_LANGUAGE_SERVER: string = 'Install R Language Server'; 18 | 19 | export function getRConfigurations(): ConfigurationPickItem[] { 20 | const ret: ConfigurationPickItem[] = []; 21 | ret.push(new ConfigurationPickItem( 22 | 'Set as R runtime', 23 | `(r.${getConfigSection()})`, 24 | graalVMHome => utils.findExecutable('R', graalVMHome) !== undefined && utils.checkRecommendedExtension('REditorSupport.r', 'R Language'), 25 | graalVMHome => utils.findExecutable('R', graalVMHome) === getConf('r').get(getConfigSection()), 26 | async graalVMHome => { 27 | const executable = utils.findExecutable('R', graalVMHome); 28 | if (executable) { 29 | return setConfig(executable); 30 | } 31 | }, 32 | async _graalVMHome => setConfig(undefined)) 33 | ); 34 | return ret; 35 | } 36 | 37 | function getConfigSection(): string { 38 | let section: string = ''; 39 | if (process.platform === 'linux') { 40 | section = 'rterm.linux'; 41 | } else if (process.platform === 'darwin') { 42 | section = 'rterm.mac'; 43 | } else if (process.platform === 'win32') { 44 | section = 'rterm.windows'; 45 | } 46 | return section; 47 | } 48 | 49 | function setConfig(path?: string) { 50 | const config = getConf('r'); 51 | let section: string = getConfigSection(); 52 | const term = section ? config.inspect(section) : undefined; 53 | if (term) { 54 | setConf(config, section, path); 55 | } 56 | const startRLS = getGVMConfig().get('languageServer.startRLanguageServer') as boolean; 57 | if (path && startRLS) { 58 | if (!isRPackageInstalled(R_LANGUAGE_SERVER_PACKAGE_NAME)) { 59 | vscode.window.showInformationMessage('Language Server package is not installed in your GraalVM R.', INSTALL_R_LANGUAGE_SERVER).then(value => { 60 | switch (value) { 61 | case INSTALL_R_LANGUAGE_SERVER: 62 | installRPackage(R_LANGUAGE_SERVER_PACKAGE_NAME); 63 | break; 64 | } 65 | }); 66 | } else { 67 | registerLanguageServer(() => startRLanguageServer()); 68 | } 69 | } 70 | } 71 | 72 | function isRPackageInstalled(name: string): boolean { 73 | const executable = utils.findExecutable('R'); 74 | if (executable) { 75 | const out = cp.execFileSync(executable, ['--quiet', '--slave', '-e', `ip<-installed.packages();is.element("${name}",ip[,1])`], { encoding: 'utf8' }); 76 | if (out.includes('TRUE')) { 77 | return true; 78 | } 79 | } 80 | return false; 81 | } 82 | 83 | export function installRPackage(name: string): boolean { 84 | const executable = utils.findExecutable('R'); 85 | if (executable) { 86 | utils.runInTerminal(`R_DEFAULT_PACKAGES=base ${executable.replace(/(\s+)/g, '\\$1')} --vanilla --quiet --slave -e 'utils::install.packages("${name}", Ncpus=1, INSTALL_opts="--no-docs --no-byte-compile --no-staged-install --no-test-load --use-vanilla")'`); 87 | return true; 88 | } 89 | return false; 90 | } 91 | 92 | function startRLanguageServer(): Thenable { 93 | return new Promise((resolve, reject) => { 94 | const gr = getGVMConfig(); 95 | const graalVMHome = getGVMHome(gr); 96 | if (graalVMHome) { 97 | const executable = utils.findExecutable('R', graalVMHome); 98 | if (executable) { 99 | let serverWorkDir: string | undefined = gr.get('languageServer.currentWorkDir') as string; 100 | if (!serverWorkDir) { 101 | serverWorkDir = vscode.workspace.rootPath; 102 | } 103 | const rServer = net.createServer(rSocket => { 104 | rServer.close(); 105 | const server = net.createServer(socket => { 106 | server.close(); 107 | socket.pipe(rSocket); 108 | const utf8Encode = new TextEncoder(); 109 | rSocket.on('data', function(serverData) { 110 | let lines = serverData.toString().split(/\r?\n/); 111 | let msgIdx = -1; 112 | let clIdx = -1; 113 | lines.forEach((line, idx) => { 114 | if (line.length === 0) { 115 | msgIdx = idx + 1; 116 | } 117 | if (line.startsWith('Content-Length:')) { 118 | clIdx = idx; 119 | } 120 | }); 121 | if (msgIdx >= 0 && clIdx >= 0) { 122 | let msg = utf8Encode.encode(lines.slice(msgIdx).join('\r\n')); 123 | lines[clIdx] = `Content-Length: ${msg.length}`; 124 | let headers = utf8Encode.encode(`${lines.slice(0, msgIdx).join('\r\n')}\r\n`); 125 | let buff = new Uint8Array(headers.length + msg.length); 126 | buff.set(headers); 127 | buff.set(msg, headers.length); 128 | socket.write(buff); 129 | } else { 130 | socket.write(serverData); 131 | } 132 | }); 133 | }); 134 | server.listen(0, '127.0.0.1', () => { 135 | resolve(`R@${(server.address() as net.AddressInfo).port}`); 136 | }); 137 | }); 138 | rServer.listen(0, '127.0.0.1', () => { 139 | const port = (rServer.address() as net.AddressInfo).port; 140 | return cp.spawn(executable, ['--quiet', '--slave', '-e', `languageserver::run(port=${port})`], { cwd: serverWorkDir }); 141 | }); 142 | } else { 143 | reject(new Error("Cannot find 'R' within your GraalVM installation.")); 144 | } 145 | } else { 146 | reject(new Error("Cannot find your GraalVM installation.")); 147 | } 148 | }); 149 | } 150 | -------------------------------------------------------------------------------- /graalvm/src/graalVMRuby.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as cp from 'child_process'; 10 | import * as utils from './utils'; 11 | import { registerLanguageServer } from './graalVMLanguageServer'; 12 | import { ConfigurationPickItem, getConf, getGVMConfig, setConf } from './graalVMConfiguration'; 13 | 14 | export const RUBY_LANGUAGE_SERVER_GEM_NAME: string = 'solargraph'; 15 | const INSTALL_RUBY_LANGUAGE_SERVER: string = 'Install Ruby Language Server'; 16 | 17 | export function getRubyConfigurations(): ConfigurationPickItem[] { 18 | const ret: ConfigurationPickItem[] = []; 19 | ret.push(new ConfigurationPickItem( 20 | 'Set as Ruby runtime', 21 | '(ruby.interpreter.commandPath)', 22 | graalVMHome => utils.findExecutable('ruby', graalVMHome) !== undefined && utils.checkRecommendedExtension('rebornix.Ruby', 'Ruby Language'), 23 | graalVMHome => utils.findExecutable('ruby', graalVMHome) === getConf('ruby').get('interpreter.commandPath'), 24 | async graalVMHome => { 25 | const executable = utils.findExecutable('ruby', graalVMHome); 26 | if (executable) { 27 | return setConfig('interpreter.commandPath', executable); 28 | } 29 | }, 30 | async _graalVMHome => setConfig('interpreter.commandPath', undefined)) 31 | ); 32 | return ret; 33 | } 34 | 35 | function setConfig(section: string, path?: string) { 36 | const config = getConf('ruby'); 37 | const term = config.inspect(section); 38 | if (term) { 39 | setConf(config, section, path); 40 | } 41 | const startRLS = getGVMConfig().get('languageServer.startRubyLanguageServer') as boolean; 42 | if (path && startRLS) { 43 | if (!isRubyGemInstalled(RUBY_LANGUAGE_SERVER_GEM_NAME)) { 44 | vscode.window.showInformationMessage('Solargraph gem is not installed in your GraalVM Ruby.', INSTALL_RUBY_LANGUAGE_SERVER).then(value => { 45 | switch (value) { 46 | case INSTALL_RUBY_LANGUAGE_SERVER: 47 | installRubyGem(RUBY_LANGUAGE_SERVER_GEM_NAME); 48 | break; 49 | } 50 | }); 51 | } else { 52 | registerLanguageServer(() => startRubyLanguageServer()); 53 | } 54 | } 55 | } 56 | 57 | function isRubyGemInstalled(name: string): boolean { 58 | const executable = utils.findExecutable('gem'); 59 | if (executable) { 60 | try { 61 | const out = cp.execFileSync(executable, ['list', '-i', name], { encoding: 'utf8' }); 62 | if (out.includes('true')) { 63 | return true; 64 | } 65 | } catch (err) { 66 | return false; 67 | } 68 | } 69 | return false; 70 | } 71 | 72 | export function installRubyGem(name: string): boolean { 73 | const executable = utils.findExecutable('gem'); 74 | if (executable) { 75 | utils.runInTerminal(`${executable.replace(/(\s+)/g, '\\$1')} install ${name}`); 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | function startRubyLanguageServer(): Thenable { 82 | return new Promise((resolve, reject) => { 83 | const executable = utils.findExecutable('solargraph'); 84 | if (executable) { 85 | const child = cp.spawn(executable, ['socket', '--port', '0']); 86 | child.stderr.on('data', data => { 87 | var match = data.toString().match(/PORT=([0-9]*)[\s]+PID=([0-9]*)/); 88 | if (match) { 89 | const port = parseInt(match[1]); 90 | resolve(`ruby@${port}`); 91 | } 92 | }); 93 | child.on('error', (err) => { 94 | reject(err); 95 | }); 96 | child.on('exit', () => { 97 | reject(new Error("Solargraph exited")); 98 | }); 99 | } else { 100 | reject(new Error("Cannot find 'solagraph' within your GraalVM installation.")); 101 | } 102 | }); 103 | } 104 | -------------------------------------------------------------------------------- /graalvm/src/sdkmanSupport.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from 'vscode'; 9 | import * as cp from "child_process"; 10 | import * as fs from "fs"; 11 | import { join } from "path"; 12 | import { readDirSyncSafe } from './utils'; 13 | 14 | const SDKMAN_DIR: string = process.env.SDKMAN_DIR ?? ""; 15 | const SDKMAN_INIT: string = join(SDKMAN_DIR, "bin", "sdkman-init.sh"); 16 | const SDKMAN_CANDIDATES_JAVA: string = join(SDKMAN_DIR, "candidates", "java"); 17 | const SDKMAN_CURRENT_JAVA: string = join(SDKMAN_CANDIDATES_JAVA, "current"); 18 | const SDKMAN_SOURCE: string = `source ${SDKMAN_INIT} ; sdk `; 19 | 20 | let SDKMAN_PRESENT: boolean | undefined = undefined; 21 | export function isSDKmanPresent(): boolean { 22 | if (SDKMAN_PRESENT === undefined) { 23 | SDKMAN_PRESENT = fs.existsSync(SDKMAN_INIT) && execSDKmanSync("v").includes("SDKMAN"); 24 | } 25 | return SDKMAN_PRESENT; 26 | } 27 | 28 | export function obtainSDKmanGVMInstallations(): [string, string][] { 29 | if (!isSDKmanPresent()) 30 | return []; 31 | return _obtainSDKmanGVMInstallations(); 32 | } 33 | 34 | function _obtainSDKmanGVMInstallations(): [string, string][] { 35 | return readDirSyncSafe(SDKMAN_CANDIDATES_JAVA) 36 | .map<[string, string]>(c => [join(SDKMAN_CANDIDATES_JAVA, c), c]) 37 | .filter(c => !fs.lstatSync(c[0]).isSymbolicLink() && c[1].endsWith("grl")); 38 | } 39 | 40 | export function obtainSDKmanUnclassifiedInstallations(): [string, string][] { 41 | if (!isSDKmanPresent()) 42 | return []; 43 | return _obtainSDKmanUnclassifiedInstallations(); 44 | } 45 | 46 | function _obtainSDKmanUnclassifiedInstallations(): [string, string][] { 47 | return readDirSyncSafe(SDKMAN_CANDIDATES_JAVA) 48 | .map<[string, string]>(c => [join(SDKMAN_CANDIDATES_JAVA, c), c]) 49 | .filter(c => fs.lstatSync(c[0]).isSymbolicLink() && c[0] !== SDKMAN_CURRENT_JAVA); 50 | } 51 | 52 | export function obtainSDKmanInstallations(): [string, string][] { 53 | if (!isSDKmanPresent()) 54 | return []; 55 | return _obtainSDKmanInstallations(); 56 | } 57 | 58 | function _obtainSDKmanInstallations(): [string, string][] { 59 | return _obtainSDKmanGVMInstallations().concat(_obtainSDKmanUnclassifiedInstallations()); 60 | } 61 | 62 | export function currentSDKmanJavaInstallation(): string | undefined { 63 | if (!isSDKmanPresent()) 64 | return undefined; 65 | return _currentSDKmanJavaInstallation(); 66 | } 67 | 68 | function _currentSDKmanJavaInstallation(): string | undefined { 69 | return fs.existsSync(SDKMAN_CURRENT_JAVA) ? fs.readlinkSync(SDKMAN_CURRENT_JAVA) : undefined; 70 | } 71 | 72 | function execSDKmanSync(command: string): string { 73 | return cp.spawnSync(SDKMAN_SOURCE + command, { encoding: "utf8", shell: vscode.env.shell }).stdout; 74 | } 75 | -------------------------------------------------------------------------------- /graalvm/src/types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | export type GraalVMComponent = { 9 | id: string; 10 | name: string; 11 | installed?: boolean; 12 | isLicenseImplicitlyAccepted?: boolean; 13 | }; 14 | 15 | export type Cache = { [P in K]: T }; -------------------------------------------------------------------------------- /graalvm/src/utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | import * as vscode from "vscode"; 9 | import * as path from 'path'; 10 | import * as fs from 'fs'; 11 | import * as cp from 'child_process'; 12 | import * as xmlparser from 'xml2js'; 13 | import { getGVMHome } from "./graalVMConfiguration"; 14 | 15 | export function random(low: number, high: number): number { 16 | return Math.floor(Math.random() * (high - low) + low); 17 | } 18 | 19 | export function findExecutable(program: string, graalVMHome?: string): string | undefined { 20 | graalVMHome = graalVMHome || getGVMHome(); 21 | if (graalVMHome) { 22 | const exists = (executablePath: string) => { 23 | if (process.platform === 'win32') { 24 | if (fs.existsSync(executablePath + '.cmd')) { 25 | return executablePath + '.cmd'; 26 | } 27 | if (fs.existsSync(executablePath + '.exe')) { 28 | return executablePath + '.exe'; 29 | } 30 | } else if (fs.existsSync(executablePath)) { 31 | return executablePath; 32 | } 33 | return undefined; 34 | } 35 | let executable = exists(path.join(graalVMHome, 'bin', program)); 36 | if (executable) { 37 | return executable; 38 | } 39 | executable = exists(path.join(graalVMHome, 'jre', 'bin', program)); 40 | if (executable) { 41 | return executable; 42 | } 43 | } 44 | return undefined; 45 | } 46 | 47 | export function findExecutables(programs: string[], graalVMHome?: string): string | undefined { 48 | return programs.map(program => findExecutable(program, graalVMHome)).find(executable => executable !== undefined); 49 | } 50 | 51 | export function readDirSyncSafe(path: string): string[] { 52 | if(fs.existsSync(path)) 53 | return fs.readdirSync(path); 54 | return []; 55 | } 56 | 57 | export async function ask(question: string, options: { option: string; fnc?: (() => any) }[], otherwise: () => any = () => undefined, modal: boolean = false, detail?: string): Promise { 58 | const select = await vscode.window.showInformationMessage(question, { modal: modal, detail: detail }, ...options.map(o => o.option)); 59 | if (!select) { 60 | return otherwise(); 61 | } 62 | const opt = options.find(o => o.option === select); 63 | if (opt && opt.fnc) { 64 | return opt.fnc(); 65 | } 66 | return; 67 | } 68 | 69 | const YES: string = 'Yes'; 70 | const NO: string = 'No'; 71 | export async function askYesNo(question: string, ifYes: (() => Y) | undefined, ifNo?: (() => N), otherwise?: () => O, modal: boolean = false, detail?: string): Promise { 72 | return ask(question, [{ option: YES, fnc: ifYes }, { option: NO, fnc: ifNo }], otherwise, modal, detail); 73 | } 74 | 75 | const INSTALL: string = 'Install'; 76 | async function askInstall(question: string, ifYes: (() => any) | undefined, otherwise?: (() => any)): Promise { 77 | return ask(question, [{option: INSTALL, fnc: ifYes}], otherwise); 78 | } 79 | 80 | export function isSamePath(): (path1: string) => ((path2: string) => boolean) { 81 | if (platform() !== PLATFORM_WINDOWS) { 82 | return (path1: string) => ((path2: string) => path1 === path2); 83 | } 84 | return (path1: string) => { 85 | const upperPath1 = path1.toUpperCase(); 86 | return (path2: string) => upperPath1 === path2.toUpperCase(); 87 | }; 88 | } 89 | 90 | export async function runInTerminal(command: string) { 91 | let terminal: vscode.Terminal | undefined = vscode.window.activeTerminal; 92 | if (!terminal) { 93 | terminal = vscode.window.createTerminal(); 94 | } 95 | terminal.show(); 96 | terminal.sendText(command); 97 | } 98 | 99 | export function checkRecommendedExtension(extensionName: string, display: string): boolean { 100 | const extension = vscode.extensions.getExtension(extensionName); 101 | if (!extension) { 102 | askInstall(`Do you want to install the recommended extensions for ${display}?`, 103 | () => runInTerminal(`code --install-extension ${extensionName}`)); 104 | } 105 | return extension !== undefined; 106 | } 107 | 108 | export function isSymlinked(dirPath: string): Promise { 109 | return new Promise((resolve, reject) => { 110 | fs.lstat(dirPath, (err, stats) => { 111 | if (err) { 112 | reject(err); 113 | } 114 | if (stats.isSymbolicLink()) { 115 | resolve(true); 116 | } else { 117 | const parent = path.dirname(dirPath); 118 | if (parent === dirPath) { 119 | resolve(false); 120 | } else { 121 | resolve(isSymlinked(parent)); 122 | } 123 | } 124 | }); 125 | }); 126 | } 127 | export const ARCH_X64: string = 'x64'; 128 | export const ARCH_AMD64: string = 'amd64'; 129 | export const ARCH_ARM64: string = 'arm64'; 130 | export const ARCH_AARCH64: string = 'aarch64'; 131 | export const ARCH_UNKNOWN: string = 'unknown'; 132 | export function getArch() { 133 | const arch = process.arch; 134 | switch (arch) { 135 | case ARCH_X64: 136 | return ARCH_AMD64; 137 | case ARCH_ARM64: 138 | return ARCH_AARCH64; 139 | default: 140 | return ARCH_UNKNOWN; 141 | } 142 | } 143 | 144 | export function killProcess(pid: number) { 145 | if (process.platform === 'win32') { 146 | try { 147 | cp.execSync(`${path.join(process.env['WINDIR'] || 'C:\\Windows', 'System32', 'taskkill.exe')} /f /t /pid ${pid}`); 148 | } catch (e) {} 149 | } else { 150 | const groupPID = -pid; 151 | try { 152 | process.kill(groupPID, 'SIGKILL'); 153 | } catch (ex: unknown) { 154 | const e = ex as Error; 155 | if (e.message === 'kill ESRCH') { 156 | try { 157 | process.kill(pid, 'SIGKILL'); 158 | } catch (e) {} 159 | } 160 | } 161 | } 162 | } 163 | 164 | export function checkFolderWritePermissions(graalVMHome: string, silent?: boolean): boolean { 165 | try { 166 | if (platform() === PLATFORM_WINDOWS) { 167 | const tmpFile = path.join(graalVMHome, 'tmp.tmp'); 168 | fs.writeFileSync(tmpFile, ''); 169 | fs.unlinkSync(tmpFile); 170 | } else { 171 | fs.accessSync(graalVMHome, fs.constants.W_OK); 172 | } 173 | return true; 174 | } catch (err) { 175 | if (!silent) { 176 | vscode.window.showErrorMessage(`Permission denied: no write access to ${graalVMHome}`); 177 | } 178 | return false; 179 | } 180 | } 181 | 182 | export const PLATFORM_WINDOWS: string = 'windows'; 183 | export const PLATFORM_WIN32: string = 'win32'; 184 | export const PLATFORM_OSX: string = 'osx'; 185 | export const PLATFORM_DARWIN: string = 'darwin'; 186 | export const PLATFORM_LINUX: string = 'linux'; 187 | export const PLATFORM_UNDEFINED: string = 'undefined'; 188 | export function platform(): string { 189 | if (process.platform === PLATFORM_LINUX) { 190 | return PLATFORM_LINUX; 191 | } else if (process.platform === PLATFORM_DARWIN) { 192 | return PLATFORM_OSX; 193 | } else if (process.platform === PLATFORM_WIN32) { 194 | return PLATFORM_WINDOWS; 195 | } 196 | return PLATFORM_UNDEFINED; 197 | } 198 | 199 | export function getUserHome(): string | undefined{ 200 | const env = process.env; 201 | if (platform() === PLATFORM_WINDOWS) { 202 | const drive = env['HOMEDRIVE']; 203 | const homePath = env['HOMEPATH']; 204 | return drive && homePath ? drive + homePath : undefined; 205 | } else { 206 | return env['HOME']; 207 | } 208 | } 209 | 210 | function toNumber(value: string, _name: string): number | string { 211 | const out = Number.parseInt(value); 212 | return Number.isSafeInteger(out) ? out : value; 213 | } 214 | 215 | function toBoolean(value: string, _name: string): boolean | string { 216 | if (value === "true") { 217 | return true; 218 | } else if (value === "false") { 219 | return false; 220 | } else { 221 | return value; 222 | } 223 | } 224 | 225 | export async function parseXMLFile(file: string, explicitArray: boolean = false): Promise { 226 | const content = readFileToString(file); 227 | return await xmlparser.parseStringPromise(content, { explicitArray: explicitArray, valueProcessors: [toNumber, toBoolean]}); 228 | } 229 | 230 | export function writeXMLFile(file: string, content: any, pretty: boolean = true) { 231 | fs.writeFileSync(file, new xmlparser.Builder({renderOpts: {pretty: pretty}}).buildObject(content)); 232 | } 233 | 234 | export function readFileToString(file: string): string { 235 | return fs.readFileSync(file).toString(); 236 | } 237 | 238 | export function readReleaseFile(gvmHome?: string): any { 239 | gvmHome = gvmHome === undefined ? getGVMHome() : gvmHome; 240 | let content: string = readFileToString(path.join(gvmHome, "release")); 241 | return parsePropertiesString(content); 242 | } 243 | 244 | export function parsePropertiesString(content: string): any { 245 | return content.split("\n") 246 | .reduce((acc: any, line: string) => { 247 | const i = line.indexOf("="); 248 | acc[line.slice(0, i)] = line.slice(i + 1); 249 | return acc; 250 | }, {}); 251 | } 252 | 253 | export function simpleProgress(message: string, task: () => Thenable): Thenable { 254 | return vscode.window.withProgress({ 255 | location: vscode.ProgressLocation.Notification, 256 | title: message, 257 | cancellable: false 258 | }, (_progress, _token) => { 259 | return task(); 260 | }); 261 | } 262 | 263 | class InputFlowAction { 264 | static back = new InputFlowAction(); 265 | static cancel = new InputFlowAction(); 266 | static resume = new InputFlowAction(); 267 | } 268 | 269 | type InputStep = (input: MultiStepInput) => Thenable; 270 | 271 | interface QuickPickParameters { 272 | title: string; 273 | step: number; 274 | totalSteps: number | undefined; 275 | items: T[]; 276 | activeItem?: T; 277 | placeholder: string; 278 | postProcess?: (value: T) => Promise; 279 | buttons?: vscode.QuickInputButton[]; 280 | shouldResume: () => Thenable; 281 | } 282 | 283 | interface InputBoxParameters { 284 | title: string; 285 | step: number; 286 | totalSteps: number; 287 | value: string; 288 | prompt: string; 289 | validate?: (value: string) => Promise; 290 | buttons?: vscode.QuickInputButton[]; 291 | shouldResume: () => Thenable; 292 | } 293 | 294 | export class MultiStepInput { 295 | 296 | static async run(start: InputStep) { 297 | const input = new MultiStepInput(); 298 | return input.stepThrough(start); 299 | } 300 | 301 | private current?: vscode.QuickInput; 302 | private steps: InputStep[] = []; 303 | 304 | private async stepThrough(start: InputStep) { 305 | let step: InputStep | void = start; 306 | while (step) { 307 | this.steps.push(step); 308 | if (this.current) { 309 | this.current.enabled = false; 310 | this.current.busy = true; 311 | } 312 | try { 313 | step = await step(this); 314 | } catch (err) { 315 | if (err === InputFlowAction.back) { 316 | this.steps.pop(); 317 | step = this.steps.pop(); 318 | } else if (err === InputFlowAction.resume) { 319 | step = this.steps.pop(); 320 | } else if (err === InputFlowAction.cancel) { 321 | step = undefined; 322 | } else { 323 | throw err; 324 | } 325 | } 326 | } 327 | if (this.current) { 328 | this.current.dispose(); 329 | } 330 | } 331 | 332 | async showQuickPick>({ title, step, totalSteps, items, activeItem, placeholder, postProcess, buttons, shouldResume }: P) { 333 | const disposables: vscode.Disposable[] = []; 334 | try { 335 | return await new Promise((resolve, reject) => { 336 | const input = vscode.window.createQuickPick(); 337 | input.title = title; 338 | input.step = step; 339 | input.totalSteps = totalSteps; 340 | input.placeholder = placeholder; 341 | input.items = items; 342 | if (activeItem) { 343 | input.activeItems = [activeItem]; 344 | } 345 | input.buttons = [ 346 | ...(this.steps.length > 1 ? [vscode.QuickInputButtons.Back] : []), 347 | ...(buttons || []) 348 | ]; 349 | input.ignoreFocusOut = true; 350 | disposables.push( 351 | input.onDidTriggerButton(item => { 352 | if (item === vscode.QuickInputButtons.Back) { 353 | reject(InputFlowAction.back); 354 | } else { 355 | resolve(item); 356 | } 357 | }), 358 | input.onDidAccept(async () => { 359 | const item = input.selectedItems[0]; 360 | if (postProcess) { 361 | input.enabled = false; 362 | input.busy = true; 363 | try { 364 | await postProcess(item); 365 | } catch(ex: unknown) { 366 | const e = ex as Error; 367 | reject(InputFlowAction.cancel); 368 | vscode.window.showErrorMessage(e.message); 369 | } 370 | input.enabled = true; 371 | input.busy = false; 372 | } 373 | resolve(item); 374 | }), 375 | input.onDidHide(() => { 376 | (async () => { 377 | reject(shouldResume && await shouldResume() ? InputFlowAction.resume : InputFlowAction.cancel); 378 | })() 379 | .catch(reject); 380 | }) 381 | ); 382 | if (this.current) { 383 | this.current.dispose(); 384 | } 385 | this.current = input; 386 | this.current.show(); 387 | }); 388 | } finally { 389 | disposables.forEach(d => d.dispose()); 390 | } 391 | } 392 | 393 | async showInputBox

({ title, step, totalSteps, value, prompt, validate, buttons, shouldResume }: P) { 394 | const disposables: vscode.Disposable[] = []; 395 | try { 396 | return await new Promise((resolve, reject) => { 397 | const input = vscode.window.createInputBox(); 398 | input.title = title; 399 | input.step = step; 400 | input.totalSteps = totalSteps; 401 | input.value = value || ''; 402 | input.prompt = prompt; 403 | input.buttons = [ 404 | ...(this.steps.length > 1 ? [vscode.QuickInputButtons.Back] : []), 405 | ...(buttons || []) 406 | ]; 407 | input.ignoreFocusOut = true; 408 | disposables.push( 409 | input.onDidTriggerButton(item => { 410 | if (item === vscode.QuickInputButtons.Back) { 411 | reject(InputFlowAction.back); 412 | } else { 413 | resolve(item); 414 | } 415 | }), 416 | input.onDidAccept(async () => { 417 | const value = input.value; 418 | input.enabled = false; 419 | input.busy = true; 420 | if (validate) { 421 | input.validationMessage = await validate(value); 422 | } 423 | if (!input.validationMessage) { 424 | resolve(value); 425 | } 426 | input.enabled = true; 427 | input.busy = false; 428 | }), 429 | input.onDidChangeValue(async () => { 430 | input.validationMessage = undefined; 431 | }), 432 | input.onDidHide(() => { 433 | (async () => { 434 | reject(shouldResume && await shouldResume() ? InputFlowAction.resume : InputFlowAction.cancel); 435 | })() 436 | .catch(reject); 437 | }) 438 | ); 439 | if (this.current) { 440 | this.current.dispose(); 441 | } 442 | this.current = input; 443 | this.current.show(); 444 | }); 445 | } finally { 446 | disposables.forEach(d => d.dispose()); 447 | } 448 | } 449 | } 450 | -------------------------------------------------------------------------------- /graalvm/syntaxes/js-polyglot-injection.json: -------------------------------------------------------------------------------- 1 | { 2 | "injectionSelector": "L:source.js -comment -(string - meta.embedded), L:source.r meta.embedded.inline.js, L:source.ruby meta.embedded.inline.js, L:source.python meta.embedded.inline.js, L:source.sl meta.embedded.inline.js", 3 | "scopeName": "js.inline.polyglot-languages", 4 | "patterns": [ 5 | { 6 | "begin": "((Polyglot)\\s*(\\.)\\s*(eval))\\s*(\\()", 7 | "beginCaptures": { 8 | "1": { 9 | "name": "meta.function-call.js" 10 | }, 11 | "2": { 12 | "name": "variable.other.object.js" 13 | }, 14 | "3": { 15 | "name": "punctuation.accessor.js" 16 | }, 17 | "4": { 18 | "name": "entity.name.function.js" 19 | }, 20 | "5": { 21 | "name": "meta.brace.round.js" 22 | } 23 | }, 24 | "end": "(\\))", 25 | "endCaptures": { 26 | "1": { 27 | "name": "meta.brace.round.js" 28 | } 29 | }, 30 | "patterns": [ 31 | { 32 | "include": "#polyglot-call-r" 33 | }, 34 | { 35 | "include": "#polyglot-call-ruby" 36 | }, 37 | { 38 | "include": "#polyglot-call-python" 39 | }, 40 | { 41 | "include": "#polyglot-call-sl" 42 | }, 43 | { 44 | "include": "source.js#expression" 45 | } 46 | ] 47 | } 48 | ], 49 | "repository": { 50 | "polyglot-call-r": { 51 | "begin": "(?:((')R('))|((\")R(\"))|((`)R(`)))\\s*(,)\\s*", 52 | "beginCaptures": { 53 | "1": { 54 | "name": "string.quoted.single.js" 55 | }, 56 | "2": { 57 | "name": "punctuation.definition.string.begin.js" 58 | }, 59 | "3": { 60 | "name": "punctuation.definition.string.end.js" 61 | }, 62 | "4": { 63 | "name": "string.quoted.double.js" 64 | }, 65 | "5": { 66 | "name": "punctuation.definition.string.begin.js" 67 | }, 68 | "6": { 69 | "name": "punctuation.definition.string.end.js" 70 | }, 71 | "7": { 72 | "name": "string.template.js" 73 | }, 74 | "8": { 75 | "name": "punctuation.definition.string.template.begin.js" 76 | }, 77 | "9": { 78 | "name": "punctuation.definition.string.template.end.js" 79 | }, 80 | "10": { 81 | "name": "punctuation.separator.comma.js" 82 | } 83 | }, 84 | "end": "(?=\\))", 85 | "patterns": [ 86 | { 87 | "include": "source.js#comment" 88 | }, 89 | { 90 | "include": "#string-inline-r" 91 | } 92 | ] 93 | }, 94 | "string-inline-r": { 95 | "patterns": [ 96 | { 97 | "include": "#string-single-inline-r" 98 | }, 99 | { 100 | "include": "#string-double-inline-r" 101 | }, 102 | { 103 | "include": "#template-inline-r" 104 | } 105 | ] 106 | }, 107 | "string-double-inline-r": { 108 | "name": "string.quoted.double.js", 109 | "contentName": "meta.embedded.inline.r", 110 | "begin": "\"", 111 | "beginCaptures": { 112 | "0": { 113 | "name": "punctuation.definition.string.begin.js" 114 | } 115 | }, 116 | "end": "(\")|((?:[^\\\\\\n])$)", 117 | "endCaptures": { 118 | "1": { 119 | "name": "punctuation.definition.string.end.js" 120 | }, 121 | "2": { 122 | "name": "invalid.illegal.newline.js" 123 | } 124 | }, 125 | "patterns": [ 126 | { 127 | "include": "source.r" 128 | } 129 | ] 130 | }, 131 | "string-single-inline-r": { 132 | "name": "string.quoted.single.js", 133 | "contentName": "meta.embedded.inline.r", 134 | "begin": "'", 135 | "beginCaptures": { 136 | "0": { 137 | "name": "punctuation.definition.string.begin.js" 138 | } 139 | }, 140 | "end": "(\\')|((?:[^\\\\\\n])$)", 141 | "endCaptures": { 142 | "1": { 143 | "name": "punctuation.definition.string.end.js" 144 | }, 145 | "2": { 146 | "name": "invalid.illegal.newline.js" 147 | } 148 | }, 149 | "patterns": [ 150 | { 151 | "include": "source.r" 152 | } 153 | ] 154 | }, 155 | "template-inline-r": { 156 | "name": "string.template.js", 157 | "contentName": "meta.embedded.inline.r", 158 | "begin": "`", 159 | "beginCaptures": { 160 | "0": { 161 | "name": "punctuation.definition.string.template.begin.js" 162 | } 163 | }, 164 | "end": "`", 165 | "endCaptures": { 166 | "0": { 167 | "name": "punctuation.definition.string.template.end.js" 168 | } 169 | }, 170 | "patterns": [ 171 | { 172 | "include": "source.r" 173 | } 174 | ] 175 | }, 176 | "polyglot-call-ruby": { 177 | "begin": "(?:((')ruby('))|((\")ruby(\"))|((`)ruby(`)))\\s*(,)\\s*", 178 | "beginCaptures": { 179 | "1": { 180 | "name": "string.quoted.single.js" 181 | }, 182 | "2": { 183 | "name": "punctuation.definition.string.begin.js" 184 | }, 185 | "3": { 186 | "name": "punctuation.definition.string.end.js" 187 | }, 188 | "4": { 189 | "name": "string.quoted.double.js" 190 | }, 191 | "5": { 192 | "name": "punctuation.definition.string.begin.js" 193 | }, 194 | "6": { 195 | "name": "punctuation.definition.string.end.js" 196 | }, 197 | "7": { 198 | "name": "string.template.js" 199 | }, 200 | "8": { 201 | "name": "punctuation.definition.string.template.begin.js" 202 | }, 203 | "9": { 204 | "name": "punctuation.definition.string.template.end.js" 205 | }, 206 | "10": { 207 | "name": "punctuation.separator.comma.js" 208 | } 209 | }, 210 | "end": "(?=\\))", 211 | "patterns": [ 212 | { 213 | "include": "source.js#comment" 214 | }, 215 | { 216 | "include": "#string-inline-ruby" 217 | } 218 | ] 219 | }, 220 | "string-inline-ruby": { 221 | "patterns": [ 222 | { 223 | "include": "#string-single-inline-ruby" 224 | }, 225 | { 226 | "include": "#string-double-inline-ruby" 227 | }, 228 | { 229 | "include": "#template-inline-ruby" 230 | } 231 | ] 232 | }, 233 | "string-double-inline-ruby": { 234 | "name": "string.quoted.double.js", 235 | "contentName": "meta.embedded.inline.ruby", 236 | "begin": "\"", 237 | "beginCaptures": { 238 | "0": { 239 | "name": "punctuation.definition.string.begin.js" 240 | } 241 | }, 242 | "end": "(\")|((?:[^\\\\\\n])$)", 243 | "endCaptures": { 244 | "1": { 245 | "name": "punctuation.definition.string.end.js" 246 | }, 247 | "2": { 248 | "name": "invalid.illegal.newline.js" 249 | } 250 | }, 251 | "patterns": [ 252 | { 253 | "include": "source.ruby" 254 | } 255 | ] 256 | }, 257 | "string-single-inline-ruby": { 258 | "name": "string.quoted.single.js", 259 | "contentName": "meta.embedded.inline.ruby", 260 | "begin": "'", 261 | "beginCaptures": { 262 | "0": { 263 | "name": "punctuation.definition.string.begin.js" 264 | } 265 | }, 266 | "end": "(\\')|((?:[^\\\\\\n])$)", 267 | "endCaptures": { 268 | "1": { 269 | "name": "punctuation.definition.string.end.js" 270 | }, 271 | "2": { 272 | "name": "invalid.illegal.newline.js" 273 | } 274 | }, 275 | "patterns": [ 276 | { 277 | "include": "source.ruby" 278 | } 279 | ] 280 | }, 281 | "template-inline-ruby": { 282 | "name": "string.template.js", 283 | "contentName": "meta.embedded.inline.ruby", 284 | "begin": "`", 285 | "beginCaptures": { 286 | "0": { 287 | "name": "punctuation.definition.string.template.begin.js" 288 | } 289 | }, 290 | "end": "`", 291 | "endCaptures": { 292 | "0": { 293 | "name": "punctuation.definition.string.template.end.js" 294 | } 295 | }, 296 | "patterns": [ 297 | { 298 | "include": "source.ruby" 299 | } 300 | ] 301 | }, 302 | "polyglot-call-python": { 303 | "begin": "(?:((')python('))|((\")python(\"))|((`)python(`)))\\s*(,)\\s*", 304 | "beginCaptures": { 305 | "1": { 306 | "name": "string.quoted.single.js" 307 | }, 308 | "2": { 309 | "name": "punctuation.definition.string.begin.js" 310 | }, 311 | "3": { 312 | "name": "punctuation.definition.string.end.js" 313 | }, 314 | "4": { 315 | "name": "string.quoted.double.js" 316 | }, 317 | "5": { 318 | "name": "punctuation.definition.string.begin.js" 319 | }, 320 | "6": { 321 | "name": "punctuation.definition.string.end.js" 322 | }, 323 | "7": { 324 | "name": "string.template.js" 325 | }, 326 | "8": { 327 | "name": "punctuation.definition.string.template.begin.js" 328 | }, 329 | "9": { 330 | "name": "punctuation.definition.string.template.end.js" 331 | }, 332 | "10": { 333 | "name": "punctuation.separator.comma.js" 334 | } 335 | }, 336 | "end": "(?=\\))", 337 | "patterns": [ 338 | { 339 | "include": "source.js#comment" 340 | }, 341 | { 342 | "include": "#string-inline-python" 343 | } 344 | ] 345 | }, 346 | "string-inline-python": { 347 | "patterns": [ 348 | { 349 | "include": "#string-single-inline-python" 350 | }, 351 | { 352 | "include": "#string-double-inline-python" 353 | }, 354 | { 355 | "include": "#template-inline-python" 356 | } 357 | ] 358 | }, 359 | "string-double-inline-python": { 360 | "name": "string.quoted.double.js", 361 | "contentName": "meta.embedded.inline.python", 362 | "begin": "\"", 363 | "beginCaptures": { 364 | "0": { 365 | "name": "punctuation.definition.string.begin.js" 366 | } 367 | }, 368 | "end": "(\")|((?:[^\\\\\\n])$)", 369 | "endCaptures": { 370 | "1": { 371 | "name": "punctuation.definition.string.end.js" 372 | }, 373 | "2": { 374 | "name": "invalid.illegal.newline.js" 375 | } 376 | }, 377 | "patterns": [ 378 | { 379 | "include": "source.python" 380 | } 381 | ] 382 | }, 383 | "string-single-inline-python": { 384 | "name": "string.quoted.single.js", 385 | "contentName": "meta.embedded.inline.python", 386 | "begin": "'", 387 | "beginCaptures": { 388 | "0": { 389 | "name": "punctuation.definition.string.begin.js" 390 | } 391 | }, 392 | "end": "(\\')|((?:[^\\\\\\n])$)", 393 | "endCaptures": { 394 | "1": { 395 | "name": "punctuation.definition.string.end.js" 396 | }, 397 | "2": { 398 | "name": "invalid.illegal.newline.js" 399 | } 400 | }, 401 | "patterns": [ 402 | { 403 | "include": "source.python" 404 | } 405 | ] 406 | }, 407 | "template-inline-python": { 408 | "name": "string.template.js", 409 | "contentName": "meta.embedded.inline.python", 410 | "begin": "`", 411 | "beginCaptures": { 412 | "0": { 413 | "name": "punctuation.definition.string.template.begin.js" 414 | } 415 | }, 416 | "end": "`", 417 | "endCaptures": { 418 | "0": { 419 | "name": "punctuation.definition.string.template.end.js" 420 | } 421 | }, 422 | "patterns": [ 423 | { 424 | "include": "source.python" 425 | } 426 | ] 427 | }, 428 | "polyglot-call-sl": { 429 | "begin": "(?:((')sl('))|((\")sl(\"))|((`)sl(`)))\\s*(,)\\s*", 430 | "beginCaptures": { 431 | "1": { 432 | "name": "string.quoted.single.js" 433 | }, 434 | "2": { 435 | "name": "punctuation.definition.string.begin.js" 436 | }, 437 | "3": { 438 | "name": "punctuation.definition.string.end.js" 439 | }, 440 | "4": { 441 | "name": "string.quoted.double.js" 442 | }, 443 | "5": { 444 | "name": "punctuation.definition.string.begin.js" 445 | }, 446 | "6": { 447 | "name": "punctuation.definition.string.end.js" 448 | }, 449 | "7": { 450 | "name": "string.template.js" 451 | }, 452 | "8": { 453 | "name": "punctuation.definition.string.template.begin.js" 454 | }, 455 | "9": { 456 | "name": "punctuation.definition.string.template.end.js" 457 | }, 458 | "10": { 459 | "name": "punctuation.separator.comma.js" 460 | } 461 | }, 462 | "end": "(?=\\))", 463 | "patterns": [ 464 | { 465 | "include": "source.js#comment" 466 | }, 467 | { 468 | "include": "#string-inline-sl" 469 | } 470 | ] 471 | }, 472 | "string-inline-sl": { 473 | "patterns": [ 474 | { 475 | "include": "#string-single-inline-sl" 476 | }, 477 | { 478 | "include": "#string-double-inline-sl" 479 | }, 480 | { 481 | "include": "#template-inline-sl" 482 | } 483 | ] 484 | }, 485 | "string-double-inline-sl": { 486 | "name": "string.quoted.double.js", 487 | "contentName": "meta.embedded.inline.sl", 488 | "begin": "\"", 489 | "beginCaptures": { 490 | "0": { 491 | "name": "punctuation.definition.string.begin.js" 492 | } 493 | }, 494 | "end": "(\")|((?:[^\\\\\\n])$)", 495 | "endCaptures": { 496 | "1": { 497 | "name": "punctuation.definition.string.end.js" 498 | }, 499 | "2": { 500 | "name": "invalid.illegal.newline.js" 501 | } 502 | }, 503 | "patterns": [ 504 | { 505 | "include": "source.sl" 506 | } 507 | ] 508 | }, 509 | "string-single-inline-sl": { 510 | "name": "string.quoted.single.js", 511 | "contentName": "meta.embedded.inline.sl", 512 | "begin": "'", 513 | "beginCaptures": { 514 | "0": { 515 | "name": "punctuation.definition.string.begin.js" 516 | } 517 | }, 518 | "end": "(\\')|((?:[^\\\\\\n])$)", 519 | "endCaptures": { 520 | "1": { 521 | "name": "punctuation.definition.string.end.js" 522 | }, 523 | "2": { 524 | "name": "invalid.illegal.newline.js" 525 | } 526 | }, 527 | "patterns": [ 528 | { 529 | "include": "source.sl" 530 | } 531 | ] 532 | }, 533 | "template-inline-sl": { 534 | "name": "string.template.js", 535 | "contentName": "meta.embedded.inline.sl", 536 | "begin": "`", 537 | "beginCaptures": { 538 | "0": { 539 | "name": "punctuation.definition.string.template.begin.js" 540 | } 541 | }, 542 | "end": "`", 543 | "endCaptures": { 544 | "0": { 545 | "name": "punctuation.definition.string.template.end.js" 546 | } 547 | }, 548 | "patterns": [ 549 | { 550 | "include": "source.sl" 551 | } 552 | ] 553 | } 554 | } 555 | } 556 | -------------------------------------------------------------------------------- /graalvm/syntaxes/python-polyglot-injection.json: -------------------------------------------------------------------------------- 1 | { 2 | "injectionSelector": "L:source.python -comment -(string - meta.embedded), L:source.js meta.embedded.inline.python, L:source.r meta.embedded.inline.python, L:source.ruby meta.embedded.inline.python, L:source.sl meta.embedded.inline.python", 3 | "scopeName": "python-inline.polyglot-languages", 4 | "patterns": [ 5 | { 6 | "begin": "polyglot\\s*(\\.)\\s*((eval)\\s*(\\())", 7 | "beginCaptures": { 8 | "1": { 9 | "name": "punctuation.separator.period.python" 10 | }, 11 | "2": { 12 | "name": "meta.function-call.python" 13 | }, 14 | "3": { 15 | "name": "meta.function-call.generic.python" 16 | }, 17 | "4": { 18 | "name": "punctuation.definition.arguments.begin.python" 19 | } 20 | }, 21 | "contentName": "meta.function-call.python meta.function-call.arguments.python", 22 | "end": "\\)", 23 | "endCaptures": { 24 | "0": { 25 | "name": "meta.function-call.python punctuation.definition.arguments.end.python" 26 | } 27 | }, 28 | "patterns": [ 29 | { 30 | "include": "#polyglot-call-js" 31 | }, 32 | { 33 | "include": "#polyglot-call-r" 34 | }, 35 | { 36 | "include": "#polyglot-call-ruby" 37 | }, 38 | { 39 | "include": "#polyglot-call-sl" 40 | }, 41 | { 42 | "include": "#function-arguments" 43 | } 44 | ] 45 | } 46 | ], 47 | "repository": { 48 | "function-arguments": { 49 | "patterns": [ 50 | { 51 | "name": "punctuation.separator.arguments.python", 52 | "match": "(,)" 53 | }, 54 | { 55 | "match": "(?x)\n (?:(?<=[,(])|^) \\s* (\\*{1,2})\n", 56 | "captures": { 57 | "1": { 58 | "name": "keyword.operator.unpacking.arguments.python" 59 | } 60 | } 61 | }, 62 | { 63 | "include": "source.python#lambda-incomplete" 64 | }, 65 | { 66 | "include": "source.python#illegal-names" 67 | }, 68 | { 69 | "match": "\\b([[:alpha:]_]\\w*)\\s*(=)(?!=)", 70 | "captures": { 71 | "1": { 72 | "name": "variable.parameter.function-call.python" 73 | }, 74 | "2": { 75 | "name": "keyword.operator.assignment.python" 76 | } 77 | } 78 | }, 79 | { 80 | "name": "keyword.operator.assignment.python", 81 | "match": "=(?!=)" 82 | }, 83 | { 84 | "include": "source.python#expression" 85 | }, 86 | { 87 | "match": "\\s*(\\))\\s*(\\()", 88 | "captures": { 89 | "1": { 90 | "name": "punctuation.definition.arguments.end.python" 91 | }, 92 | "2": { 93 | "name": "punctuation.definition.arguments.begin.python" 94 | } 95 | } 96 | } 97 | ] 98 | }, 99 | "polyglot-call-js": { 100 | "begin": "(language)\\s*(=)\\s*((['\"])js(\\4))\\s*(,)\\s*", 101 | "beginCaptures": { 102 | "1" : { 103 | "name": "variable.parameter.function-call.python" 104 | }, 105 | "2": { 106 | "name": "keyword.operator.assignment.python" 107 | }, 108 | "3": { 109 | "name": "string.quoted.single.python" 110 | }, 111 | "4": { 112 | "name": "punctuation.definition.string.begin.python" 113 | }, 114 | "5": { 115 | "name": "punctuation.definition.string.end.python" 116 | }, 117 | "6": { 118 | "name": "punctuation.separator.arguments.python" 119 | } 120 | }, 121 | "end": "(?=\\))", 122 | "patterns": [ 123 | { 124 | "include": "#strings-inline-js" 125 | }, 126 | { 127 | "include": "#function-arguments" 128 | } 129 | ] 130 | }, 131 | "strings-inline-js": { 132 | "patterns": [ 133 | { 134 | "name": "string.quoted.multi.python", 135 | "contentName": "meta.embedded.inline.js", 136 | "begin": "(string)\\s*(=)\\s*('''|\"\"\")", 137 | "beginCaptures": { 138 | "1": { 139 | "name": "variable.parameter.function-call.python" 140 | }, 141 | "2": { 142 | "name": "keyword.operator.assignment.python" 143 | }, 144 | "3": { 145 | "name": "punctuation.definition.string.begin.python" 146 | } 147 | }, 148 | "end": "(\\3)", 149 | "endCaptures": { 150 | "1": { 151 | "name": "punctuation.definition.string.end.python" 152 | } 153 | }, 154 | "patterns": [ 155 | { 156 | "include": "source.js" 157 | } 158 | ] 159 | }, 160 | { 161 | "name": "string.quoted.single.python", 162 | "contentName": "meta.embedded.inline.js", 163 | "begin": "(string)\\s*(=)\\s*(['\"])", 164 | "beginCaptures": { 165 | "1": { 166 | "name": "variable.parameter.function-call.python" 167 | }, 168 | "2": { 169 | "name": "keyword.operator.assignment.python" 170 | }, 171 | "3": { 172 | "name": "punctuation.definition.string.begin.python" 173 | } 174 | }, 175 | "end": "(\\3)|((?=|<>|<|>" 202 | }, 203 | { 204 | "name": "keyword.operator.arithmetic.sl", 205 | "match": "\\*|/|-|\\+" 206 | }, 207 | { 208 | "name": "keyword.operator.assignment.sl", 209 | "match": "\\=" 210 | } 211 | ] 212 | }, 213 | "numeric-literal": { 214 | "name": "constant.numeric.decimal.sl", 215 | "match": "\\b(? https://webpack.js.org/configuration/node/ 15 | 16 | plugins: [ 17 | new ESLintPlugin({extensions: ['ts']}) 18 | ], 19 | 20 | entry: { 21 | extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ 22 | debug: './src/graalVMDebugAdapter.ts' 23 | }, 24 | output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ 25 | path: path.resolve(__dirname, 'dist'), 26 | filename: '[name].js', 27 | libraryTarget: "commonjs2", 28 | devtoolModuleFilenameTemplate: "../[resource-path]", 29 | }, 30 | devtool: 'source-map', 31 | externals: { 32 | vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ 33 | bufferutil: "bufferutil", 34 | "utf-8-validate": "utf-8-validate", 35 | }, 36 | resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 37 | extensions: ['.ts', '.js'], 38 | symlinks: false 39 | }, 40 | module: { 41 | rules: [{ 42 | test: /\.ts$/, 43 | exclude: /node_modules/, 44 | include: path.resolve(__dirname, 'src'), 45 | use: [{ 46 | loader: 'ts-loader' 47 | }] 48 | }] 49 | }, 50 | } 51 | const devConf = { 52 | target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ 53 | 54 | plugins: [ 55 | new webpack.AutomaticPrefetchPlugin() 56 | ], 57 | 58 | entry: { 59 | extension: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ 60 | debug: './src/graalVMDebugAdapter.ts' 61 | }, 62 | output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ 63 | path: path.resolve(__dirname, 'dist'), 64 | filename: '[name].js', 65 | libraryTarget: "commonjs2", 66 | devtoolModuleFilenameTemplate: "../[resource-path]", 67 | }, 68 | devtool: 'source-map', 69 | externals: { 70 | vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ 71 | bufferutil: "bufferutil", 72 | "utf-8-validate": "utf-8-validate", 73 | }, 74 | resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 75 | extensions: ['.ts', '.js'], 76 | symlinks: false, 77 | cacheWithContext: false 78 | }, 79 | module: { 80 | rules: [{ 81 | test: /\.ts$/, 82 | exclude: /node_modules/, 83 | include: path.resolve(__dirname, 'src'), 84 | use: [{ 85 | loader: 'ts-loader', 86 | options: { 87 | transpileOnly: true, // https://github.com/TypeStrong/ts-loader#faster-builds 88 | } 89 | }] 90 | }] 91 | }, 92 | optimization: { 93 | minimize: false 94 | }, 95 | cache: { 96 | type: 'filesystem', 97 | buildDependencies: { 98 | // This makes all dependencies of this file - build dependencies 99 | config: [__filename], 100 | // By default webpack and loaders are build dependencies 101 | }, 102 | }, 103 | } 104 | // https://webpack.js.org/configuration/mode/#mode-none 105 | module.exports = (env, argv) => { 106 | if (argv.mode === 'development') { 107 | return devConf; 108 | } 109 | 110 | if (argv.mode === 'production') { 111 | return config; 112 | } 113 | return config; 114 | }; 115 | -------------------------------------------------------------------------------- /graalvm/webviews/icons/law_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/webviews/icons/law_dark.png -------------------------------------------------------------------------------- /graalvm/webviews/icons/law_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/graalvm/vscode-extensions/074169e1333bdccd913b02962b6116e5cd61f5c5/graalvm/webviews/icons/law_light.png -------------------------------------------------------------------------------- /graalvm/webviews/licenseCheck.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | License 10 | 11 | 12 | 13 |

14 |

You must review and accept the Oracle License Agreement to download this software.

15 |
16 | {{{license}}} 17 |
18 |
19 | 20 | 21 | 22 | Oracle Privacy Policy 23 |
24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /graalvm/webviews/scripts/licenseCheck.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 6 | */ 7 | 8 | const vscode = acquireVsCodeApi(); 9 | document.addEventListener("DOMContentLoaded", function(event) { 10 | const emailInput = document.getElementById('email'); 11 | emailInput.addEventListener('input', () => { 12 | emailInput.setCustomValidity(''); 13 | if (!emailInput.checkValidity()) { 14 | emailInput.setCustomValidity('Please provide a valid email address'); 15 | } 16 | }); 17 | const acceptButton = document.getElementById('accept'); 18 | acceptButton.addEventListener('click', () => { 19 | if (emailInput.reportValidity()) { 20 | vscode.postMessage({ command: 'accepted', email: emailInput.value }); 21 | } 22 | }); 23 | const rejectButton = document.getElementById('reject'); 24 | rejectButton.addEventListener('click', () => { 25 | vscode.postMessage({ command: 'rejected' }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /graalvm/webviews/styles/licenseCheck.css: -------------------------------------------------------------------------------- 1 | button { 2 | display: inline-block; 3 | border: none; 4 | padding: 6px 12px; 5 | margin-right: 12px; 6 | text-decoration: none; 7 | background: var(--vscode-button-background); 8 | color: var(--vscode-button-foreground); 9 | font-family: sans-serif; 10 | font-size: 14px; 11 | cursor: pointer; 12 | text-align: center; 13 | -webkit-appearance: none; 14 | -moz-appearance: none; 15 | } 16 | button:hover, button:focus { 17 | background: var(--vscode-button-hoverBackground); 18 | } 19 | button:focus { 20 | outline: 1px solid var(--vscode-button-hoverBackground); 21 | } 22 | input { 23 | border: var(--vscode-input-border); 24 | padding: 6px 12px; 25 | margin-right: 12px; 26 | background: var(--vscode-input-background); 27 | color: var(--vscode-input-foreground); 28 | } 29 | input:focus { 30 | outline-color: var(--vscode-focusBorder); 31 | } 32 | .section { 33 | display: flex; 34 | flex-flow: column nowrap; 35 | padding: 3px 25px; 36 | max-height: 97vh; 37 | } 38 | .panel { 39 | color: var(--vscode-sideBarTitle-foreground); 40 | background-color: var(--vscode-sideBar-background); 41 | border: 1px solid var(--vscode-sideBar-border); 42 | padding: 12px; 43 | margin-bottom: 24px; 44 | max-height: 100vh; 45 | overflow-x: hidden; 46 | overflow-y: auto; 47 | } 48 | -------------------------------------------------------------------------------- /mx.vscode/mx_vscode.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # The Universal Permissive License (UPL), Version 1.0 6 | # 7 | # Subject to the condition set forth below, permission is hereby granted to any 8 | # person obtaining a copy of this software, associated documentation and/or 9 | # data (collectively the "Software"), free of charge and under any and all 10 | # copyright rights in the Software, and any and all patent rights owned or 11 | # freely licensable by each licensor hereunder covering either (i) the 12 | # unmodified Software as contributed to or provided by such licensor, or (ii) 13 | # the Larger Works (as defined below), to deal in both 14 | # 15 | # (a) the Software, and 16 | # 17 | # (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 18 | # one is included with the Software each a "Larger Work" to which the Software 19 | # is contributed by such licensors), 20 | # 21 | # without restriction, including without limitation the rights to copy, create 22 | # derivative works of, display, perform, and distribute the Software and make, 23 | # use, sell, offer for sale, import, export, have made, and have sold the 24 | # Software and the Larger Work(s), and to sublicense the foregoing rights on 25 | # either these or other terms. 26 | # 27 | # This license is subject to the following condition: 28 | # 29 | # The above copyright notice and either this complete permission notice or at a 30 | # minimum a reference to the UPL must be included in all copies or substantial 31 | # portions of the Software. 32 | # 33 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 39 | # SOFTWARE. 40 | # 41 | import mx 42 | import os 43 | import mx_gate 44 | from os.path import join, isfile, exists 45 | from mx_gate import Task 46 | 47 | _suite = mx.suite('vscode') 48 | 49 | BUILD_NUMBER = mx.get_env("BUILD_NUMBER", None) 50 | JOB_NAME = mx.get_env("JOB_NAME", None) 51 | 52 | def _vscode_gate_runner(args, tasks): 53 | with Task('VSCode UnitTests', tasks, tags=['test']) as t: 54 | if t: mx.run(['mx', 'build'], nonZeroIsFatal=True) 55 | 56 | mx_gate.add_gate_runner(_suite, _vscode_gate_runner) 57 | 58 | class VSCodeExtensionProject(mx.ArchivableProject): 59 | def __init__(self, suite, name, deps, workingSets, theLicense, mxLibs=None, **args): 60 | mx.ArchivableProject.__init__(self, suite, name, deps, workingSets, theLicense) 61 | self.dir = join(suite.dir, name) 62 | 63 | def archive_prefix(self): 64 | return '' 65 | 66 | def output_dir(self): 67 | return self.dir 68 | 69 | def getResults(self, replaceVar=False): 70 | results = [] 71 | for root, _, files in os.walk(self.output_dir()): 72 | for fil in files: 73 | if fil.endswith(".vsix"): 74 | results.append(join(root, fil)) 75 | return results 76 | 77 | def getBuildTask(self, args): 78 | return VSCodeExtensionBuildTask(self, args) 79 | 80 | class VSCodeExtensionBuildTask(mx.ArchivableBuildTask): 81 | def __init__(self, subject, args): 82 | mx.ArchivableBuildTask.__init__(self, subject, args, 1) 83 | 84 | def __str__(self): 85 | return 'Building VS Code Extension for {}'.format(self.subject) 86 | 87 | def newestInput(self): 88 | inputPaths = [] 89 | for path in [join(self.subject.dir, m) for m in ['', 'images', 'snippets', 'src', 'syntaxes']]: 90 | if exists(path): 91 | inputPaths.extend(join(path, f) for f in os.listdir(path) if isfile(join(path, f))) 92 | return mx.TimeStampFile.newest(inputPaths) 93 | 94 | def needsBuild(self, newestInput): 95 | out = self.newestOutput() 96 | if not out or self.newestInput().isNewerThan(out): 97 | return (True, None) 98 | return (False, None) 99 | 100 | def build(self): 101 | vsce = join(_suite.dir, 'node_modules', '.bin', 'vsce') 102 | if not exists(vsce): 103 | mx.run(['npm', 'install'], nonZeroIsFatal=True, cwd=_suite.dir) 104 | mx.run(['npm', 'install'], nonZeroIsFatal=True, cwd=self.subject.dir) 105 | if JOB_NAME and 'release' not in JOB_NAME: # Append BUILD_NUMBER to non-release Jenkins builds. 106 | command_output = mx.OutputCapture() 107 | mx.run(['node', '-pe', 'require(\'./package.json\').version'], nonZeroIsFatal=True, cwd=self.subject.dir, out=command_output) 108 | mx.run(['npm', 'version', command_output.data.strip() + '-' + BUILD_NUMBER], nonZeroIsFatal=True, cwd=self.subject.dir) 109 | mx.run([vsce, 'package', '--allow-star-activation', '--baseImagesUrl', 'https://github.com/graalvm/vscode-extensions/raw/master/' + self.subject.name], nonZeroIsFatal=True, cwd=self.subject.dir) 110 | mx.run(['npm', 'version', command_output.data.strip()], nonZeroIsFatal=True, cwd=self.subject.dir) 111 | else: 112 | mx.run([vsce, 'package', '--allow-star-activation', '--baseImagesUrl', 'https://github.com/graalvm/vscode-extensions/raw/master/' + self.subject.name], nonZeroIsFatal=True, cwd=self.subject.dir) 113 | 114 | def clean(self, forBuild=False): 115 | for fil in self.subject.getResults(): 116 | os.remove(fil) 117 | for path in [join(self.subject.dir, m) for m in ['dist', 'node_modules']]: 118 | if exists(path): 119 | mx.rmtree(path) 120 | -------------------------------------------------------------------------------- /mx.vscode/suite.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # The Universal Permissive License (UPL), Version 1.0 6 | # 7 | # Subject to the condition set forth below, permission is hereby granted to any 8 | # person obtaining a copy of this software, associated documentation and/or 9 | # data (collectively the "Software"), free of charge and under any and all 10 | # copyright rights in the Software, and any and all patent rights owned or 11 | # freely licensable by each licensor hereunder covering either (i) the 12 | # unmodified Software as contributed to or provided by such licensor, or (ii) 13 | # the Larger Works (as defined below), to deal in both 14 | # 15 | # (a) the Software, and 16 | # 17 | # (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 18 | # one is included with the Software each a "Larger Work" to which the Software 19 | # is contributed by such licensors), 20 | # 21 | # without restriction, including without limitation the rights to copy, create 22 | # derivative works of, display, perform, and distribute the Software and make, 23 | # use, sell, offer for sale, import, export, have made, and have sold the 24 | # Software and the Larger Work(s), and to sublicense the foregoing rights on 25 | # either these or other terms. 26 | # 27 | # This license is subject to the following condition: 28 | # 29 | # The above copyright notice and either this complete permission notice or at a 30 | # minimum a reference to the UPL must be included in all copies or substantial 31 | # portions of the Software. 32 | # 33 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 39 | # SOFTWARE. 40 | # 41 | suite = { 42 | "mxversion" : "5.213.0", 43 | "name" : "vscode", 44 | 45 | "defaultLicense" : "UPL", 46 | 47 | "projects" : { 48 | "graalvm" : { 49 | "class": "VSCodeExtensionProject", 50 | }, 51 | "graalvm-pack" : { 52 | "dependencies" : [ 53 | "graalvm" 54 | ], 55 | "class": "VSCodeExtensionProject", 56 | }, 57 | }, 58 | 59 | "distributions": { 60 | "VS_CODE_EXTENSIONS": { 61 | "type": "zip", 62 | "layout" : { 63 | "./" : [ 64 | "dependency:graalvm/*", 65 | "dependency:graalvm-pack/*" 66 | ] 67 | } 68 | }, 69 | }, 70 | 71 | "licenses" : { 72 | "UPL" : { 73 | "name" : "Universal Permissive License, Version 1.0", 74 | "url" : "http://opensource.org/licenses/UPL", 75 | } 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@vscode/vsce": "2.24.0" 4 | } 5 | } 6 | --------------------------------------------------------------------------------