├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── continuous.yml │ ├── release.yml │ └── testPR.yml ├── .gitignore ├── .project ├── .smalltalk.ston ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── readme.moosebook └── src ├── .properties ├── BaselineOfPharoLanguageServer ├── BaselineOfPharoLanguageServer.class.st └── package.st ├── PLS-Pharo8-Extension ├── RTView.extension.st └── package.st ├── PLS-Pharo9-Extension ├── RSCanvas.extension.st └── package.st ├── PLSDAP-Helpers ├── String.extension.st └── package.st ├── PharoDAP ├── Array.extension.st ├── Boolean.extension.st ├── CommandLineDapUIManager.class.st ├── DAPAttachEvent.class.st ├── DAPAttachResponse.class.st ├── DAPBreakpointChangedEvent.class.st ├── DAPBreakpointCreatedEvent.class.st ├── DAPBreakpointEvent.class.st ├── DAPBreakpointRemovedEvent.class.st ├── DAPCancelArguments.class.st ├── DAPCancelRequest.class.st ├── DAPCancelResponse.class.st ├── DAPCapabilities.class.st ├── DAPConfigurationDoneResponse.class.st ├── DAPContext.class.st ├── DAPContinueResponse.class.st ├── DAPContinuedEvent.class.st ├── DAPDisconnectResponse.class.st ├── DAPError.class.st ├── DAPErrorResponse.class.st ├── DAPEvaluateResponse.class.st ├── DAPEvent.class.st ├── DAPHandler.class.st ├── DAPIncorrectJSON.class.st ├── DAPInitializeRequest.class.st ├── DAPInitializeRequestArguments.class.st ├── DAPInitializeResponse.class.st ├── DAPInitializedEvent.class.st ├── DAPInvalidParameters.class.st ├── DAPJsonableObject.class.st ├── DAPLaunchRequest.class.st ├── DAPLaunchRequestArguments.class.st ├── DAPLaunchResponse.class.st ├── DAPMessage.class.st ├── DAPNextResponse.class.st ├── DAPNonExistentHandler.class.st ├── DAPOupsDebuggerSelector.class.st ├── DAPRequest.class.st ├── DAPResponse.class.st ├── DAPScope.class.st ├── DAPScopesResponse.class.st ├── DAPServer.class.st ├── DAPSetBreakpointsResponse.class.st ├── DAPSetExceptionBreakpointsResponse.class.st ├── DAPSource.class.st ├── DAPSourceResponse.class.st ├── DAPStackFrame.class.st ├── DAPStackTraceResponse.class.st ├── DAPStepInResponse.class.st ├── DAPStepOutResponse.class.st ├── DAPStoppedEvent.class.st ├── DAPTScope.class.st ├── DAPTVariableScope.class.st ├── DAPTerminatedEvent.class.st ├── DAPThread.class.st ├── DAPThreadsResponse.class.st ├── DAPVariable.class.st ├── DAPVariablesResponse.class.st ├── Dictionary.extension.st ├── Error.extension.st ├── Integer.extension.st ├── OCExtraBindingScope.extension.st ├── String.extension.st └── package.st ├── PharoLanguageClient ├── PLCAnswerProcessor.class.st ├── PLCContext.class.st ├── PLCMessageSendHandler.class.st ├── PLCPythonServerConfigurationRunner.class.st ├── PLCServerConfigurationRunner.class.st ├── TPLCClient.trait.st └── package.st ├── PharoLanguageClientLocal ├── PLCClient.class.st ├── PLCCodePresenter.class.st ├── PLCLRubScrolledTextMorph.class.st ├── PLCLTextStyler.class.st ├── PLCLocalClient.class.st ├── SpMorphicPLCCodeAdapter.class.st ├── SpPLCPharoCodePresenter.class.st ├── StPLCPPlayground.class.st ├── StPLCPPlaygroundPage.class.st ├── StPLCPPlaygroundPagePresenter.class.st ├── TextGhost.class.st └── package.st ├── PharoLanguageProtocol-Tests ├── PLCDummyServerConfigurationRunner.class.st ├── PLPDummyClient.class.st ├── PLPDummyServer.class.st ├── PLPTests.class.st ├── TPLPCommonTest.class.st └── package.st ├── PharoLanguageProtocol ├── PLPCancelParams.class.st ├── PLPClientCapabilities.class.st ├── PLPInitializeParams.class.st ├── PLPInlineCompletionContext.class.st ├── PLPInlineCompletionParams.class.st ├── PLPInlineCompletionTriggerKind.class.st ├── PLPTextDocumentClientCapabilities.class.st ├── PLPTextDocumentContentChangeEvent.class.st ├── PLPTextDocumentItem.class.st ├── PLPTextDocumentPositionParams.class.st ├── ReadWriteStream.extension.st ├── SocketStream.extension.st ├── StdioStream.extension.st ├── TPLPCommon.trait.st └── package.st ├── PharoLanguageServer-Gtk ├── PLSApplication.class.st └── package.st ├── PharoLanguageServer-Tests ├── PLSDocumentTest.class.st ├── PLSFormaterTest.class.st ├── PLSScriptDocumentTest.class.st ├── PLSServerTest.class.st ├── PLSStringTest.class.st ├── PLSTonelDocumentTest.class.st └── package.st └── PharoLanguageServer ├── AbstractBinaryFileStream.extension.st ├── Class.extension.st ├── Exception.extension.st ├── Form.extension.st ├── JRPCSuccessResponseObject.extension.st ├── MCMethodDefinition.extension.st ├── NECClassVarEntry.extension.st ├── NECEntry.extension.st ├── NECInstVarEntry.extension.st ├── NECSymbolEntry.extension.st ├── NECVariableEntry.extension.st ├── Object.extension.st ├── PLSAbstractServer.class.st ├── PLSApplyWorkspaceEditParams.class.st ├── PLSBinder.class.st ├── PLSCellMimetype.class.st ├── PLSCellOutput.class.st ├── PLSCodeAction.class.st ├── PLSCodeActionContext.class.st ├── PLSCodeActionKind.class.st ├── PLSCodeActionOptions.class.st ├── PLSCodeActionTriggerKind.class.st ├── PLSCodeDescription.class.st ├── PLSCodeLens.class.st ├── PLSCodeLensOptions.class.st ├── PLSCommand.class.st ├── PLSCompletion.class.st ├── PLSCompletionEngine.class.st ├── PLSCompletionItem.class.st ├── PLSCompletionItemKind.class.st ├── PLSCompletionItemTag.class.st ├── PLSCompletionList.class.st ├── PLSCompletionOptions.class.st ├── PLSContext.class.st ├── PLSDiagnostic.class.st ├── PLSDiagnosticOptions.class.st ├── PLSDiagnosticsParamsEngine.class.st ├── PLSDocument.class.st ├── PLSDocumentFormattingOptions.class.st ├── PLSDocumentSymbol.class.st ├── PLSDocumentSymbolOptions.class.st ├── PLSErroredMCMethodDefinition.class.st ├── PLSFormater.class.st ├── PLSFullDocumentDiagnosticsReport.class.st ├── PLSHover.class.st ├── PLSHoverOptions.class.st ├── PLSInitializeResult.class.st ├── PLSInlineCompletionItem.class.st ├── PLSInlineCompletionList.class.st ├── PLSInsertTextFormat.class.st ├── PLSLocation.class.st ├── PLSLogMessage.class.st ├── PLSLogTraceParams.class.st ├── PLSMCMethodDefinition.class.st ├── PLSMessageProcessor.class.st ├── PLSMessageSendHandler.class.st ├── PLSMessageType.class.st ├── PLSParameterInformation.class.st ├── PLSPosition.class.st ├── PLSPublishDiagnosticsParams.class.st ├── PLSRange.class.st ├── PLSScriptDocument.class.st ├── PLSServer.class.st ├── PLSServerCapabilities.class.st ├── PLSShowDocument.class.st ├── PLSShowMessage.class.st ├── PLSSignatureHelp.class.st ├── PLSSignatureHelpClientCapabilities.class.st ├── PLSSignatureInformation.class.st ├── PLSSymbolKind.class.st ├── PLSTextDocumentClientCapabilities.class.st ├── PLSTextDocumentEdit.class.st ├── PLSTextDocumentIdentifier.class.st ├── PLSTextDocumentSyncKind.class.st ├── PLSTextDocumentSyncOptions.class.st ├── PLSTextEdit.class.st ├── PLSTonelDocument.class.st ├── PLSTonelFormater.class.st ├── PLSTonelParser.class.st ├── PLSTraceValue.class.st ├── PLSTypeDefinitionOptions.class.st ├── PLSUIManager.class.st ├── PLSUnchangedDocumentDiagnosticReport.class.st ├── PLSVariable.class.st ├── PLSVersionedTextDocumentIdentifier.class.st ├── PLSWorkDoneProgressOptions.class.st ├── PLSWorkspaceEdit.class.st ├── Package.extension.st ├── String.extension.st └── package.st /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | ###################################### 2 | # Based on Ubuntu image 3 | ###################################### 4 | FROM ubuntu 5 | 6 | LABEL maintainer="Benoit Verhaeghe" 7 | 8 | ###################################### 9 | # Update Ubuntu apt and install some tools 10 | ###################################### 11 | RUN apt-get update \ 12 | && apt-get install -y wget git unzip libpulse0 libasound2 libcairo2 13 | 14 | 15 | # Required for the readme moosebook 16 | RUN apt-get install -y openjdk-17-jdk openjdk-17-jre \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | ###################################### 20 | # Have an own directory for the tool 21 | ###################################### 22 | RUN mkdir -p /root/pharo 23 | WORKDIR /root/pharo 24 | 25 | ###################################### 26 | # Download Pharo using Zeroconf & start script 27 | ###################################### 28 | RUN mkdir /root/pharo/Moose64-12-PLS 29 | WORKDIR /root/pharo/Moose64-12-PLS 30 | RUN wget https://github.com/badetitou/Pharo-LanguageServer/releases/download/v5.0.1/Moose64-12-PLS.zip 31 | RUN unzip Moose64-12-PLS.zip 32 | 33 | WORKDIR /root/pharo/ 34 | RUN mkdir /root/pharo/pharo-vm 35 | WORKDIR /root/pharo/pharo-vm 36 | RUN wget https://files.pharo.org/get-files/120/pharo-vm-Linux-aarch64-latest.zip 37 | RUN unzip pharo-vm-Linux-aarch64-latest.zip 38 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/javascript-node 3 | { 4 | "name": "Pharo", 5 | "build": { 6 | "dockerfile": "Dockerfile" 7 | }, 8 | 9 | // Configure tool-specific properties. 10 | "customizations": { 11 | // Configure properties specific to VS Code. 12 | "vscode": { 13 | // Set *default* container specific settings.json values on container create. 14 | "settings": { 15 | "pharo.pathToVM": "/root/pharo/pharo-vm/pharo", 16 | "pharo.pathToImage": "/root/pharo/Moose64-12-PLS/Moose64-12-PLS.image", 17 | "pharo.headless": true, 18 | "pharo.debug": false 19 | }, 20 | 21 | // Add the IDs of extensions you want installed when the container is created. 22 | "extensions": [ 23 | "badetitou.pharo-language-server" 24 | ] 25 | } 26 | } 27 | 28 | // Use 'postCreateCommand' to run commands after the container is created. 29 | // "postCreateCommand": "yarn install" 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/continuous.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Continuous 4 | 5 | env: 6 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 7 | 8 | # Controls when the action will run. Triggers the workflow on push or pull request 9 | # events but only for the development branch 10 | on: 11 | push: 12 | branches: 13 | - main 14 | - v* 15 | 16 | jobs: 17 | build: 18 | runs-on: ubuntu-latest 19 | env: 20 | PROJECT_NAME: ${{ matrix.smalltalk }}-PLS 21 | strategy: 22 | matrix: 23 | smalltalk: [ Pharo64-12, Moose64-12 ] 24 | name: ${{ matrix.smalltalk }} 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: hpi-swa/setup-smalltalkCI@v1 28 | with: 29 | smalltalk-image: ${{ matrix.smalltalk }} 30 | - run: smalltalkci -s ${{ matrix.smalltalk }} 31 | shell: bash 32 | timeout-minutes: 15 33 | 34 | - name: Coveralls 35 | uses: coverallsapp/github-action@master 36 | if: ${{ matrix.smalltalk == 'Moose64-12' }} 37 | with: 38 | github-token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | env: 4 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | env: 14 | PROJECT_NAME: ${{ matrix.smalltalk }}-PLS 15 | strategy: 16 | matrix: 17 | smalltalk: [ Pharo64-12, Moose64-12 ] 18 | name: ${{ matrix.smalltalk }} 19 | steps: 20 | - uses: actions/checkout@v2 21 | - uses: hpi-swa/setup-smalltalkCI@v1 22 | with: 23 | smalltalk-image: ${{ matrix.smalltalk }} 24 | - run: smalltalkci -s ${{ matrix.smalltalk }} 25 | shell: bash 26 | timeout-minutes: 15 27 | 28 | - name: package 29 | run: | 30 | mv /home/runner/.smalltalkCI/_builds/* . 31 | mv TravisCI.image $PROJECT_NAME.image 32 | mv TravisCI.changes $PROJECT_NAME.changes 33 | echo ${${{ matrix.smalltalk }}} | sed -e 's/\.//g' > pharo.version 34 | zip -r $PROJECT_NAME.zip $PROJECT_NAME.image $PROJECT_NAME.changes *.sources pharo.version 35 | ls 36 | 37 | - name: Get release 38 | id: get_release 39 | uses: bruceadams/get-release@v1.2.2 40 | env: 41 | GITHUB_TOKEN: ${{ github.token }} 42 | 43 | - name: Upload Release Asset 44 | id: upload-release-asset 45 | uses: actions/upload-release-asset@v1 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | with: 49 | upload_url: ${{ steps.get_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 50 | asset_path: ./${{ env.PROJECT_NAME }}.zip 51 | asset_name: ${{ env.PROJECT_NAME }}.zip 52 | asset_content_type: application/zip 53 | -------------------------------------------------------------------------------- /.github/workflows/testPR.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | env: 4 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 5 | 6 | # Controls when the action will run. Triggers the workflow on push or pull request 7 | # events but only for the development branch 8 | on: 9 | pull_request: 10 | branches: 11 | - v* 12 | - main 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | env: 18 | PROJECT_NAME: ${{ matrix.smalltalk }}-FAST-Java 19 | strategy: 20 | matrix: 21 | smalltalk: [ Pharo64-12, Moose64-12 ] 22 | name: ${{ matrix.smalltalk }} 23 | steps: 24 | - uses: actions/checkout@v2 25 | - uses: hpi-swa/setup-smalltalkCI@v1 26 | with: 27 | smalltalk-image: ${{ matrix.smalltalk }} 28 | - run: smalltalkci -s ${{ matrix.smalltalk }} 29 | shell: bash 30 | timeout-minutes: 15 31 | 32 | # Auto Reneraku 33 | - name: Generate a token 34 | id: generate-token 35 | uses: actions/create-github-app-token@v1 36 | with: 37 | app-id: ${{ secrets.AUTO_RENERAKU_APP_ID }} 38 | private-key: ${{ secrets.AUTO_RENERAKU_PRIVATE_KEY }} 39 | - name: AutoReneraku 40 | uses: badetitou/AutoReneraku@main 41 | with: 42 | pat: ${{ steps.generate-token.outputs.token }} 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | { 2 | 'srcDirectory' : 'src' 3 | } -------------------------------------------------------------------------------- /.smalltalk.ston: -------------------------------------------------------------------------------- 1 | SmalltalkCISpec { 2 | #loading : [ 3 | SCIMetacelloLoadSpec { 4 | #baseline : 'PharoLanguageServer', 5 | #directory : 'src', 6 | #ignoreImage : true, 7 | #onConflict : #useIncoming, 8 | #onUpgrade : #useIncoming 9 | } 10 | ], 11 | #testing : { 12 | #coverage : { 13 | #packages : [ 'PharoLanguageServer.*', 'PLS-.*', 'PharoLanguageClient.*', 'PharoLanguageProtocol' ], 14 | #format : #lcov 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Pharo", 4 | "Tonel" 5 | ] 6 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pharo Language Server 2 | 3 | [![Continuous](https://github.com/badetitou/Pharo-LanguageServer/actions/workflows/continuous.yml/badge.svg)](https://github.com/badetitou/Pharo-LanguageServer/actions/workflows/continuous.yml) 4 | [![Pharo 12](https://img.shields.io/badge/Pharo-12-%23aac9ff.svg)](https://github.com/pharo-project/pharo) 5 | [![Moose version](https://img.shields.io/badge/Moose-12-%23aac9ff.svg)](https://github.com/moosetechnology/Moose) 6 | [![Coverage Status](https://coveralls.io/repos/github/badetitou/Pharo-LanguageServer/badge.svg?branch=v5)](https://coveralls.io/github/badetitou/Pharo-LanguageServer?branch=v5) 7 | 8 | I am an implementation of the [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/implementors/servers/) for the [Pharo programming language](https://pharo.org/). 9 | My main goal is to provide a unique interface for several generic IDE to manipulate a Pharo environment. 10 | 11 | I am used by the following client extensions: 12 | 13 | - [vscode-pharo](https://github.com/badetitou/vscode-pharo) 14 | - [vscode-eclipse](https://github.com/badetitou/eclipse-pharo) *Really only a POC. But you might be interested to have a look at it.* 15 | 16 | > If you experiement with other IDE, do not hesitate to contact us in an Issue :) 17 | 18 | ## Features 19 | 20 | As a language server, I accept two Pharo/SmallTalk formats: 21 | 22 | - *.st* for smalltalk script (as you can see in a playground). 23 | - *.class.st* for tonel files. 24 | 25 | Most of the features are available for both formats. 26 | 27 | - Code highlighting 28 | - Hover 29 | - Auto-completion 30 | 31 | ### Script specific features 32 | 33 | - Code formatting 34 | 35 | ### Tonel specific features 36 | 37 | - Saving the file create/update the corresponding class in the image 38 | 39 | ## Installation 40 | 41 | Execute this code in any Pharo10/11 Image 42 | 43 | ```Smalltalk 44 | Metacello new 45 | githubUser: 'badetitou' project: 'Pharo-LanguageServer' commitish: 'v5' path: 'src'; 46 | baseline: 'PharoLanguageServer'; 47 | load 48 | ``` 49 | 50 | > Or download a pre-existing image in the [release](https://github.com/badetitou/Pharo-LanguageServer/releases) section. 51 | 52 | ## Usage 53 | 54 | Once you have an image with the project installed, you can run it using 55 | 56 | ```sh 57 | /path/to/vm/pharo [--headless] /path/to/pls.image st /path/to/run-server.st 58 | ``` 59 | 60 | In above example, we used an another file named `run-server.st` that is used to define the Pharo script that run the code. 61 | You can find the definition of this file for the [vscode extension](https://github.com/badetitou/vscode-pharo/blob/main/res/run-server.st) and for the [eclipse extension](https://github.com/badetitou/eclipse-pharo/blob/main/res/run-server.st). 62 | 63 | Basically the file looks like this 64 | 65 | ```st 66 | | server | 67 | "Stop and reset potential existing instance in the image you start" 68 | PLSServer reset. 69 | "Create a new Language Server" 70 | server := PLSServer new. 71 | "Start the new language server" 72 | server start. 73 | ``` 74 | 75 | By default, the server will start a socket and give you the port of the opened socket in the standard output. 76 | If you want to use standard input/ouput to deal with communication, you can use the folowing option: 77 | 78 | ```st 79 | server := PLSServer new 80 | withStdIO: true; 81 | yourself 82 | ``` 83 | 84 | > This option is less tested and might create bug with Pharo writing to the standard output for other reason 85 | -------------------------------------------------------------------------------- /src/.properties: -------------------------------------------------------------------------------- 1 | { 2 | #format : #tonel 3 | } -------------------------------------------------------------------------------- /src/BaselineOfPharoLanguageServer/BaselineOfPharoLanguageServer.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'BaselineOfPharoLanguageServer', 3 | #superclass : 'BaselineOf', 4 | #category : 'BaselineOfPharoLanguageServer', 5 | #package : 'BaselineOfPharoLanguageServer' 6 | } 7 | 8 | { #category : 'baselines' } 9 | BaselineOfPharoLanguageServer >> baseline: spec [ 10 | 11 | self defineDependencies: spec. 12 | self definePackages: spec. 13 | self defineGroups: spec 14 | ] 15 | 16 | { #category : 'baselines' } 17 | BaselineOfPharoLanguageServer >> customProjectAttributes [ 18 | self class environment at: #RTView ifPresent: [ ^ #(#WithRoassal2) ]. 19 | self class environment at: #RSCanvas ifPresent: [ ^ #(#WithRoassal3) ]. 20 | ^ #() 21 | ] 22 | 23 | { #category : 'baselines' } 24 | BaselineOfPharoLanguageServer >> defineDependencies: spec [ 25 | 26 | spec 27 | baseline: 'JRPC' with: [ 28 | spec 29 | repository: 'github://juliendelplanque/JRPC:v3.2.1/src'; 30 | loads: #( 'Deployment' ) ]; 31 | import: 'JRPC'. 32 | spec 33 | baseline: 'MoreLogger' 34 | with: [ spec repository: 'github://badetitou/MoreLogger:main/src' ]. 35 | spec 36 | baseline: 'SpecGtk' 37 | with: [ spec repository: 'github://pharo-spec/Spec-Gtk:/src' ]. 38 | 39 | spec 40 | baseline: 'LLMAPI' 41 | with: [ spec repository: 'github://Evref-BL/Pharo-LLMAPI:main/src' ]. 42 | ] 43 | 44 | { #category : 'baselines' } 45 | BaselineOfPharoLanguageServer >> defineGroups: spec [ 46 | 47 | spec group: 'default' with: #( 'LSP' 'DAP' 'LSC' 'Tests' ). 48 | spec group: 'LSC' with: #( 'PharoLanguageClient' ). 49 | spec 50 | group: 'LSP' 51 | with: 52 | #( 'PLSDAP-Helpers' 'PharoLanguageServer' 'PharoLanguageServer-Tests' 53 | 'PLS-Pharo9-Extension' ). 54 | spec group: 'LSP-GTK' with: #( 'LSP' 'PharoLanguageServer-Gtk' ). 55 | spec group: 'DAP' with: #( 'PharoDAP' ). 56 | spec group: 'Tests' with: #( 'PharoLanguageProtocol-Tests' ). 57 | spec 58 | group: 'localClient' 59 | with: #( 'default' 'PharoLanguageClientLocal' ) 60 | ] 61 | 62 | { #category : 'baselines' } 63 | BaselineOfPharoLanguageServer >> definePackages: spec [ 64 | "common" 65 | 66 | spec package: 'PharoLanguageProtocol'. 67 | spec 68 | package: 'PharoLanguageProtocol-Tests' 69 | with: [ 70 | spec requires: #( 'PharoLanguageServer' 'PharoLanguageClient' ) ]. 71 | "server" 72 | spec 73 | package: 'PLSDAP-Helpers'; 74 | package: 'PharoLanguageServer' with: [ 75 | spec requires: 76 | #( 'JRPC' 'PLSDAP-Helpers' 'MoreLogger' 'PharoLanguageProtocol' 77 | 'LLMAPI' ) ]; 78 | package: 'PharoLanguageServer-Tests' 79 | with: [ spec requires: #( 'PharoLanguageServer' ) ]; 80 | package: 'PharoDAP' 81 | with: [ spec requires: #( 'MoreLogger' 'PLSDAP-Helpers' ) ]; 82 | package: 'PharoLanguageServer-Gtk' 83 | with: [ spec requires: #( 'SpecGtk' ) ]. 84 | spec package: 'PLS-Pharo9-Extension'. 85 | 86 | "client" 87 | spec 88 | package: 'PharoLanguageClient' 89 | with: [ spec requires: #( 'JRPC' 'PharoLanguageProtocol' ) ]. 90 | 91 | spec 92 | package: 'PharoLanguageClienLocal' 93 | with: [ spec requires: #( 'PharoLanguageClient' ) ] 94 | ] 95 | -------------------------------------------------------------------------------- /src/BaselineOfPharoLanguageServer/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : 'BaselineOfPharoLanguageServer' } 2 | -------------------------------------------------------------------------------- /src/PLS-Pharo8-Extension/RTView.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #RTView } 2 | 3 | { #category : #'*PLS-Pharo8-Extension' } 4 | RTView >> plsPrintString [ 5 | ^ String streamContents: [ :stream | (RTSVGExporter new view: self) exportOnStream: stream ] 6 | ] 7 | -------------------------------------------------------------------------------- /src/PLS-Pharo8-Extension/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'PLS-Pharo8-Extension' } 2 | -------------------------------------------------------------------------------- /src/PLS-Pharo9-Extension/RSCanvas.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #RSCanvas } 2 | 3 | { #category : #'*PLS-Pharo9-Extension' } 4 | RSCanvas >> asPLSCellOutput [ 5 | 6 | | string | 7 | string := (self createMorph extent: 500 @ 500) asForm plsPrintString. 8 | ^ { 9 | (PLSCellOutput content: string mimetype: PLSCellMimetype markdown). 10 | (PLSCellOutput content: string mimetype: PLSCellMimetype html) } 11 | ] 12 | -------------------------------------------------------------------------------- /src/PLS-Pharo9-Extension/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'PLS-Pharo9-Extension' } 2 | -------------------------------------------------------------------------------- /src/PLSDAP-Helpers/String.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : #String } 2 | 3 | { #category : #'*PLSDAP-Helpers' } 4 | String >> findCloseBracesFor: startIndex [ 5 | 6 | | pos nestLevel | 7 | pos := startIndex + 1. 8 | nestLevel := 1. 9 | [ pos <= self size ] 10 | whileTrue: [ (self at: pos) = ${ 11 | ifTrue: [ nestLevel := nestLevel + 1 ]. 12 | (self at: pos) = $} 13 | ifTrue: [ nestLevel := nestLevel - 1 ]. 14 | nestLevel = 0 15 | ifTrue: [ ^ pos ]. 16 | pos := pos + 1 ]. 17 | ^ 0 18 | ] 19 | -------------------------------------------------------------------------------- /src/PLSDAP-Helpers/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : #'PLSDAP-Helpers' } 2 | -------------------------------------------------------------------------------- /src/PharoDAP/Array.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'Array' } 2 | 3 | { #category : '*PharoDAP' } 4 | Array >> asDAPJSON [ 5 | ^ self collect: #asDAPJSON 6 | ] 7 | -------------------------------------------------------------------------------- /src/PharoDAP/Boolean.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'Boolean' } 2 | 3 | { #category : '*PharoDAP' } 4 | Boolean >> asDAPJSON [ 5 | ^ self 6 | ] 7 | -------------------------------------------------------------------------------- /src/PharoDAP/CommandLineDapUIManager.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'CommandLineDapUIManager', 3 | #superclass : 'NonInteractiveUIManager', 4 | #category : 'PharoDAP-UIManager', 5 | #package : 'PharoDAP', 6 | #tag : 'UIManager' 7 | } 8 | 9 | { #category : 'debug' } 10 | CommandLineDapUIManager >> debugProcess: process context: context label: title fullView: bool notification: notificationString [ 11 | 12 | (OupsDebugRequest newForContext: context) 13 | process: process; 14 | label: title; 15 | submit 16 | ] 17 | 18 | { #category : 'handle debug requests' } 19 | CommandLineDapUIManager >> handleDebugRequest: aDebugRequest [ 20 | | debuggerOpeningStrategy oupsSystem | 21 | 22 | oupsSystem := OupsDebuggerSystem new. 23 | aDebugRequest debugSession logStackToFileIfNeeded. 24 | oupsSystem performPreDebugActionsIn: aDebugRequest. 25 | oupsSystem ensureExceptionIn: aDebugRequest debugSession. 26 | debuggerOpeningStrategy := oupsSystem debuggerSelectionStrategy. 27 | debuggerOpeningStrategy openDebuggerForSession:aDebugRequest debugSession. 28 | oupsSystem suspendDebuggedProcess: aDebugRequest 29 | ] 30 | 31 | { #category : 'debug' } 32 | CommandLineDapUIManager >> handleError: anError log: shouldLog [ 33 | 34 | self handleDebugRequest: (OupsDebugRequest newForException: anError) 35 | 36 | ] 37 | 38 | { #category : 'handle debug requests' } 39 | CommandLineDapUIManager >> handleWarningDebugRequest: aWarningDebugRequest [ 40 | 41 | self handleDebugRequest: aWarningDebugRequest 42 | ] 43 | 44 | { #category : 'ui requests' } 45 | CommandLineDapUIManager >> inform: aString [ 46 | | ws | 47 | ws := (FileLocator home / 'dap_inform') ensureCreateFile writeStream. 48 | ws nextPutAll: aString. 49 | ws flush;close. 50 | 51 | ] 52 | 53 | { #category : 'default actions' } 54 | CommandLineDapUIManager >> unhandledErrorDefaultAction: anException [ 55 | 56 | anException debug 57 | 58 | 59 | ] 60 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPAttachEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPAttachEvent', 3 | #superclass : 'DAPEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'as yet unclassified' } 10 | DAPAttachEvent >> initialize [ 11 | super initialize. 12 | event := 'initialized' 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPAttachResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPAttachResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPBreakpointChangedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPBreakpointChangedEvent', 3 | #superclass : 'DAPBreakpointEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPBreakpointChangedEvent >> initialize [ 11 | super initialize. 12 | self body at:#reason put:#changed 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPBreakpointCreatedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPBreakpointCreatedEvent', 3 | #superclass : 'DAPBreakpointEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPBreakpointCreatedEvent >> initialize [ 11 | super initialize. 12 | self body at:#reason put:#new 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPBreakpointEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPBreakpointEvent', 3 | #superclass : 'DAPEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'instance creation' } 10 | DAPBreakpointEvent class >> newFromABreakpoint: aBpDictionary [ 11 | | i | 12 | i:= self new. 13 | i body at:#breakpoint put:aBpDictionary. 14 | ^ i 15 | 16 | ] 17 | 18 | { #category : 'initialization' } 19 | DAPBreakpointEvent >> initialize [ 20 | super initialize. 21 | self event: 'breakpoint'. 22 | self body: Dictionary new 23 | ] 24 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPBreakpointRemovedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPBreakpointRemovedEvent', 3 | #superclass : 'DAPBreakpointEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPBreakpointRemovedEvent >> initialize [ 11 | super initialize. 12 | self body at:#reason put:#removed 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPCancelArguments.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPCancelArguments', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'requestId', 6 | 'progressId' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPCancelRequest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPCancelRequest', 3 | #superclass : 'DAPRequest', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPCancelRequest >> initialize [ 11 | super initialize. 12 | command := 'cancel' 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPCancelResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPCancelResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPCapabilities.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPCapabilities', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'supportsConfigurationDoneRequest', 6 | 'supportsFunctionBreakpoints', 7 | 'supportsConditionalBreakpoints', 8 | 'supportsHitConditionalBreakpoints', 9 | 'supportsEvaluateForHovers', 10 | 'exceptionBreakpointFilters', 11 | 'supportsStepBack', 12 | 'supportsSetVariable', 13 | 'supportsRestartFrame', 14 | 'supportsGotoTargetsRequest', 15 | 'supportsStepInTargetsRequest', 16 | 'supportsCompletionsRequest', 17 | 'completionTriggerCharacters', 18 | 'supportsModulesRequest', 19 | 'additionalModuleColumns', 20 | 'supportedChecksumAlgorithms', 21 | 'supportsRestartRequest', 22 | 'supportsExceptionOptions', 23 | 'supportsValueFormattingOptions', 24 | 'supportsExceptionInfoRequest', 25 | 'supportTerminateDebuggee', 26 | 'supportsDelayedStackTraceLoading', 27 | 'supportsLoadedSourcesRequest', 28 | 'supportsLogPoints', 29 | 'supportsTerminateThreadsRequest', 30 | 'supportsSetExpression', 31 | 'supportsTerminateRequest', 32 | 'supportsDataBreakpoints', 33 | 'supportsReadMemoryRequest', 34 | 'supportsDisassembleRequest', 35 | 'supportsCancelRequest', 36 | 'supportsBreakpointLocationsRequest', 37 | 'supportsClipboardContext', 38 | 'supportsSteppingGranularity', 39 | 'supportsInstructionBreakpoints', 40 | 'supportsExceptionFilterOptions' 41 | ], 42 | #category : 'PharoDAP-Types', 43 | #package : 'PharoDAP', 44 | #tag : 'Types' 45 | } 46 | 47 | { #category : 'converting' } 48 | DAPCapabilities >> asDAPJSON [ 49 | 50 | | dic | 51 | dic := super asDAPJSON. 52 | self supportsDelayedStackTraceLoading ifNotNil: [ 53 | dic 54 | at: #supportsDelayedStackTraceLoading 55 | put: self supportsDelayedStackTraceLoading ]. 56 | dic at: #supportTerminateDebuggee put: true. 57 | ^ dic 58 | ] 59 | 60 | { #category : 'initialization' } 61 | DAPCapabilities >> initialize [ 62 | super initialize. 63 | supportsDelayedStackTraceLoading := true. 64 | supportsConfigurationDoneRequest := true. 65 | supportsDataBreakpoints := true. 66 | supportsConditionalBreakpoints := true. 67 | ] 68 | 69 | { #category : 'accessing' } 70 | DAPCapabilities >> supportsDelayedStackTraceLoading [ 71 | ^ supportsDelayedStackTraceLoading 72 | ] 73 | 74 | { #category : 'accessing' } 75 | DAPCapabilities >> supportsDelayedStackTraceLoading: anObject [ 76 | supportsDelayedStackTraceLoading := anObject 77 | ] 78 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPConfigurationDoneResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPConfigurationDoneResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPContext.class.st: -------------------------------------------------------------------------------- 1 | " 2 | The server use me to store informations such as the text item 3 | " 4 | Class { 5 | #name : 'DAPContext', 6 | #superclass : 'Object', 7 | #instVars : [ 8 | 'textItems', 9 | 'messageProcesses' 10 | ], 11 | #category : 'PharoDAP', 12 | #package : 'PharoDAP' 13 | } 14 | 15 | { #category : 'initialization' } 16 | DAPContext >> initialize [ 17 | textItems := Dictionary new. 18 | messageProcesses := Dictionary new. 19 | ] 20 | 21 | { #category : 'message processing' } 22 | DAPContext >> messageProcesses [ 23 | ^ messageProcesses 24 | ] 25 | 26 | { #category : 'message processing' } 27 | DAPContext >> messageProcesses: anObject [ 28 | messageProcesses := anObject 29 | ] 30 | 31 | { #category : 'message processing' } 32 | DAPContext >> messageProcessesAt: anId [ 33 | ^ anId ifNotNil: [ self messageProcesses at: anId ifAbsent:[ nil ] ] 34 | ] 35 | 36 | { #category : 'message processing' } 37 | DAPContext >> messageProcessesAt: anId put: aProcess [ 38 | anId ifNotNil: [ self messageProcesses at: anId put: aProcess ] 39 | ] 40 | 41 | { #category : 'text item' } 42 | DAPContext >> removeItem: aURI [ 43 | ^ textItems removeKey: aURI 44 | ] 45 | 46 | { #category : 'message processing' } 47 | DAPContext >> removeMessageProcess: anId [ 48 | anId ifNotNil: [ self messageProcesses removeKey: anId ifAbsent:["ignore"] ] 49 | ] 50 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPContinueResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPContinueResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'allThreadsContinued' 6 | ], 7 | #category : 'PharoDAP-Structure', 8 | #package : 'PharoDAP', 9 | #tag : 'Structure' 10 | } 11 | 12 | { #category : 'accessing' } 13 | DAPContinueResponse >> allThreadsContinued [ 14 | "If true, the 'continue' request has ignored the specified thread and continued all threads instead. 15 | If this attribute is missing a value of 'true' is assumed for backward compatibility." 16 | 17 | ^ allThreadsContinued 18 | ] 19 | 20 | { #category : 'accessing' } 21 | DAPContinueResponse >> allThreadsContinued: anObject [ 22 | allThreadsContinued := anObject 23 | ] 24 | 25 | { #category : 'accessing' } 26 | DAPContinueResponse >> asDAPJSON [ 27 | | dic | 28 | self body at: #allThreadsContinued put: self allThreadsContinued. 29 | dic := super asDAPJSON. 30 | ^ dic 31 | ] 32 | 33 | { #category : 'initialization' } 34 | DAPContinueResponse >> initialize [ 35 | super initialize. 36 | body := Dictionary new. 37 | "set to true by default until we can undle multi thread debugging" 38 | allThreadsContinued := true 39 | ] 40 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPContinuedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPContinuedEvent', 3 | #superclass : 'DAPEvent', 4 | #instVars : [ 5 | 'threadId', 6 | 'allThreadsContinued' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'accessing' } 14 | DAPContinuedEvent >> allThreadsContinued [ 15 | 16 | ^ allThreadsContinued ifNil:[ allThreadsContinued := true ] 17 | ] 18 | 19 | { #category : 'accessing' } 20 | DAPContinuedEvent >> allThreadsContinued: anObject [ 21 | 22 | allThreadsContinued := anObject 23 | ] 24 | 25 | { #category : 'as yet unclassified' } 26 | DAPContinuedEvent >> asDAPJSON [ 27 | | dic | 28 | 29 | self body at: #threadId put: self threadId. 30 | self body at: #allThreadsContinued put: self allThreadsContinued. 31 | dic := super asDAPJSON. 32 | ^ dic 33 | ] 34 | 35 | { #category : 'as yet unclassified' } 36 | DAPContinuedEvent >> initialize [ 37 | super initialize. 38 | body := Dictionary new. 39 | event := 'continued' 40 | ] 41 | 42 | { #category : 'accessing' } 43 | DAPContinuedEvent >> threadId [ 44 | ^ threadId 45 | ] 46 | 47 | { #category : 'accessing' } 48 | DAPContinuedEvent >> threadId: anObject [ 49 | threadId := anObject 50 | ] 51 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPDisconnectResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPDisconnectResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'accessing' } 10 | DAPDisconnectResponse >> asDAPJSON [ 11 | ^ Dictionary new 12 | ] 13 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPError.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPError', 3 | #superclass : 'Error', 4 | #category : 'PharoDAP-Error', 5 | #package : 'PharoDAP', 6 | #tag : 'Error' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPErrorResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPErrorResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPEvaluateResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPEvaluateResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'result', 6 | 'variablesReference' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'accessing' } 14 | DAPEvaluateResponse >> asDAPJSON [ 15 | | dic | 16 | self body at: #result put: self result. 17 | self body at: #variableReferences put: self variablesReference. 18 | dic := super asDAPJSON. 19 | ^ dic 20 | ] 21 | 22 | { #category : 'accessing' } 23 | DAPEvaluateResponse >> initialize [ 24 | super initialize. 25 | body := Dictionary new 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPEvaluateResponse >> result [ 30 | ^ result 31 | ] 32 | 33 | { #category : 'accessing' } 34 | DAPEvaluateResponse >> result: anObject [ 35 | result := anObject 36 | ] 37 | 38 | { #category : 'accessing' } 39 | DAPEvaluateResponse >> variablesReference [ 40 | ^ variablesReference 41 | ] 42 | 43 | { #category : 'accessing' } 44 | DAPEvaluateResponse >> variablesReference: anObject [ 45 | variablesReference := anObject 46 | ] 47 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPEvent', 3 | #superclass : 'DAPMessage', 4 | #instVars : [ 5 | 'event', 6 | 'body' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'converting' } 14 | DAPEvent >> asDAPJSON [ 15 | | dic | 16 | dic := super asDAPJSON. 17 | self body ifNotNil: [ dic add: #body -> self body asDAPJSON ]. 18 | self event ifNotNil: [ dic add: #event -> self event ]. 19 | ^ dic 20 | ] 21 | 22 | { #category : 'accessing' } 23 | DAPEvent >> body [ 24 | ^ body 25 | ] 26 | 27 | { #category : 'accessing' } 28 | DAPEvent >> body: anObject [ 29 | body := anObject 30 | ] 31 | 32 | { #category : 'accessing' } 33 | DAPEvent >> event [ 34 | ^ event 35 | ] 36 | 37 | { #category : 'accessing' } 38 | DAPEvent >> event: anObject [ 39 | event := anObject 40 | ] 41 | 42 | { #category : 'as yet unclassified' } 43 | DAPEvent >> initialize [ 44 | super initialize. 45 | type := 'event' 46 | ] 47 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPHandler.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPHandler', 3 | #superclass : 'Object', 4 | #instVars : [ 5 | 'methodName', 6 | 'receiver', 7 | 'messageSelector' 8 | ], 9 | #category : 'PharoDAP', 10 | #package : 'PharoDAP' 11 | } 12 | 13 | { #category : 'accessing' } 14 | DAPHandler >> checkParametersForRequest: aDAPRequestObject [ 15 | aDAPRequestObject arguments 16 | ifNil: [ 17 | self parametersCount = 0 18 | ifFalse: [ DAPInvalidParameters signal ] ]. 19 | 20 | (aDAPRequestObject arguments ifNil: [ #() ]) size = self parametersCount 21 | ifFalse: [ DAPInvalidParameters signal ]. 22 | 23 | (aDAPRequestObject arguments isDictionary 24 | and: [ ((aDAPRequestObject params keys union: self parametersNames) size ~= self parametersCount) ]) 25 | ifTrue: [ DAPInvalidParameters signal ] 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPHandler >> executeWithArguments: anArrayOrDictionary [ 30 | ^ self execute: [ self 31 | send: self messageSelector 32 | to: self receiver 33 | with: anArrayOrDictionary ] recordedAs: self messageSelector printString 34 | ] 35 | 36 | { #category : 'accessing' } 37 | DAPHandler >> messageSelector [ 38 | ^ messageSelector 39 | ] 40 | 41 | { #category : 'accessing' } 42 | DAPHandler >> messageSelector: anObject [ 43 | messageSelector := anObject 44 | ] 45 | 46 | { #category : 'accessing' } 47 | DAPHandler >> methodName [ 48 | ^ methodName 49 | ] 50 | 51 | { #category : 'accessing' } 52 | DAPHandler >> methodName: anObject [ 53 | methodName := anObject 54 | ] 55 | 56 | { #category : 'accessing' } 57 | DAPHandler >> parametersCount [ 58 | "Returns the number of parameters expected by the handler." 59 | ^ self parametersNames size 60 | ] 61 | 62 | { #category : 'accessing' } 63 | DAPHandler >> parametersNames [ 64 | ^ (self receiver class >> self messageSelector) argumentNames 65 | ] 66 | 67 | { #category : 'accessing' } 68 | DAPHandler >> receiver [ 69 | ^ receiver 70 | ] 71 | 72 | { #category : 'accessing' } 73 | DAPHandler >> receiver: anObject [ 74 | receiver := anObject 75 | ] 76 | 77 | { #category : 'accessing' } 78 | DAPHandler >> send: aSelector to: aReceiver with: arguments [ 79 | ^ aReceiver perform: aSelector with: arguments 80 | ] 81 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPIncorrectJSON.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPIncorrectJSON', 3 | #superclass : 'DAPError', 4 | #category : 'PharoDAP-Error', 5 | #package : 'PharoDAP', 6 | #tag : 'Error' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPInitializeRequest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPInitializeRequest', 3 | #superclass : 'DAPRequest', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPInitializeRequest >> initialize [ 11 | super initialize. 12 | command := 'initialize' 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPInitializeRequestArguments.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPInitializeRequestArguments', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'clientID', 6 | 'clientName', 7 | 'adapterID', 8 | 'locale', 9 | 'linesStartAt1', 10 | 'columnsStartAt1', 11 | 'pathFormat', 12 | 'supportsVariableType', 13 | 'supportsVariablePaging', 14 | 'supportsRunInTerminalRequest', 15 | 'supportsMemoryReferences', 16 | 'supportsProgressReporting', 17 | 'supportsInvalidatedEvent' 18 | ], 19 | #category : 'PharoDAP-Structure', 20 | #package : 'PharoDAP', 21 | #tag : 'Structure' 22 | } 23 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPInitializeResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPInitializeResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPInitializedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPInitializedEvent', 3 | #superclass : 'DAPEvent', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'as yet unclassified' } 10 | DAPInitializedEvent >> initialize [ 11 | super initialize. 12 | event := 'initialized' 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPInvalidParameters.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPInvalidParameters', 3 | #superclass : 'DAPError', 4 | #category : 'PharoDAP-Error', 5 | #package : 'PharoDAP', 6 | #tag : 'Error' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPJsonableObject.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPJsonableObject', 3 | #superclass : 'Object', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'converting' } 10 | DAPJsonableObject >> asDAPJSON [ 11 | ^ { } asDictionary 12 | ] 13 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPLaunchRequest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPLaunchRequest', 3 | #superclass : 'DAPRequest', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPLaunchRequest >> initialize [ 11 | super initialize. 12 | command := 'launch' 13 | ] 14 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPLaunchRequestArguments.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPLaunchRequestArguments', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'noDebug', 6 | '__restart' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'accessing' } 14 | DAPLaunchRequestArguments >> __restart [ 15 | ^ __restart 16 | ] 17 | 18 | { #category : 'accessing' } 19 | DAPLaunchRequestArguments >> __restart: anObject [ 20 | __restart := anObject 21 | ] 22 | 23 | { #category : 'accessing' } 24 | DAPLaunchRequestArguments >> noDebug [ 25 | ^ noDebug 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPLaunchRequestArguments >> noDebug: anObject [ 30 | noDebug := anObject 31 | ] 32 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPLaunchResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPLaunchResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPMessage.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPMessage', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'seq', 6 | 'type' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'converting' } 14 | DAPMessage >> asDAPJSON [ 15 | | dic | 16 | dic := super asDAPJSON. 17 | self seq ifNotNil: [ dic add: #seq -> self seq ]. 18 | self type ifNotNil: [ dic add: #type -> self type ]. 19 | ^ dic 20 | ] 21 | 22 | { #category : 'accessing' } 23 | DAPMessage >> beConvertedBy: aDAPMessageProcessor [ 24 | ^ aDAPMessageProcessor convertDAPJsonableObjectToJSON: self 25 | ] 26 | 27 | { #category : 'accessing' } 28 | DAPMessage >> seq [ 29 | ^ seq 30 | ] 31 | 32 | { #category : 'accessing' } 33 | DAPMessage >> seq: anObject [ 34 | seq := anObject 35 | ] 36 | 37 | { #category : 'accessing' } 38 | DAPMessage >> type [ 39 | ^ type 40 | ] 41 | 42 | { #category : 'accessing' } 43 | DAPMessage >> type: anObject [ 44 | type := anObject 45 | ] 46 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPNextResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPNextResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPNonExistentHandler.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPNonExistentHandler', 3 | #superclass : 'DAPError', 4 | #category : 'PharoDAP-Error', 5 | #package : 'PharoDAP', 6 | #tag : 'Error' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPOupsDebuggerSelector.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPOupsDebuggerSelector', 3 | #superclass : 'OupsSingleDebuggerSelector', 4 | #category : 'PharoDAP-Oups', 5 | #package : 'PharoDAP', 6 | #tag : 'Oups' 7 | } 8 | 9 | { #category : 'iterating' } 10 | DAPOupsDebuggerSelector >> nextDebugger [ 11 | Transcript crShow: 'dap next debugger'. 12 | ^ debuggers first 13 | ] 14 | 15 | { #category : 'iterating' } 16 | DAPOupsDebuggerSelector >> with: blabla [ 17 | 18 | ] 19 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPRequest.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPRequest', 3 | #superclass : 'DAPMessage', 4 | #instVars : [ 5 | 'command', 6 | 'arguments' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'instance creation' } 14 | DAPRequest class >> newFromJSON: aJSONObject [ 15 | | deserializeMe | 16 | deserializeMe := self new 17 | seq: (aJSONObject at: #seq); 18 | command: (aJSONObject at: #command). 19 | aJSONObject 20 | at: #arguments 21 | ifPresent: [ :args | deserializeMe arguments: args ]. 22 | ^ deserializeMe 23 | ] 24 | 25 | { #category : 'accessing' } 26 | DAPRequest >> arguments [ 27 | ^ arguments 28 | ] 29 | 30 | { #category : 'accessing' } 31 | DAPRequest >> arguments: anObject [ 32 | arguments := anObject 33 | ] 34 | 35 | { #category : 'accessing' } 36 | DAPRequest >> command [ 37 | ^ command 38 | ] 39 | 40 | { #category : 'accessing' } 41 | DAPRequest >> command: anObject [ 42 | command := anObject 43 | ] 44 | 45 | { #category : 'initialization' } 46 | DAPRequest >> convertErrorToResponse: anError [ 47 | ^ DAPErrorResponse new 48 | ] 49 | 50 | { #category : 'initialization' } 51 | DAPRequest >> initialize [ 52 | super initialize. 53 | type := 'request' 54 | ] 55 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPResponse', 3 | #superclass : 'DAPMessage', 4 | #instVars : [ 5 | 'request_seq', 6 | 'success', 7 | 'command', 8 | 'message', 9 | 'body' 10 | ], 11 | #category : 'PharoDAP-Structure', 12 | #package : 'PharoDAP', 13 | #tag : 'Structure' 14 | } 15 | 16 | { #category : 'accessing' } 17 | DAPResponse >> asDAPJSON [ 18 | | dic | 19 | dic := super asDAPJSON. 20 | self body ifNotNil: [ dic add: #body -> self body asDAPJSON ]. 21 | self command ifNotNil: [ dic add: #command -> self command ]. 22 | self message ifNotNil: [ dic add: #message -> self message ]. 23 | self request_seq ifNotNil: [ dic add: #request_seq -> self request_seq ]. 24 | self success ifNotNil: [ dic add: #success -> self success ]. 25 | ^ dic 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPResponse >> body [ 30 | ^ body 31 | ] 32 | 33 | { #category : 'accessing' } 34 | DAPResponse >> body: anObject [ 35 | body := anObject 36 | ] 37 | 38 | { #category : 'accessing' } 39 | DAPResponse >> command [ 40 | ^ command 41 | ] 42 | 43 | { #category : 'accessing' } 44 | DAPResponse >> command: anObject [ 45 | command := anObject 46 | ] 47 | 48 | { #category : 'initialization' } 49 | DAPResponse >> initialize [ 50 | super initialize. 51 | type := 'response'. 52 | success := true 53 | ] 54 | 55 | { #category : 'accessing' } 56 | DAPResponse >> message [ 57 | ^ message 58 | ] 59 | 60 | { #category : 'accessing' } 61 | DAPResponse >> message: anObject [ 62 | message := anObject 63 | ] 64 | 65 | { #category : 'accessing' } 66 | DAPResponse >> request_seq [ 67 | ^ request_seq 68 | ] 69 | 70 | { #category : 'accessing' } 71 | DAPResponse >> request_seq: anObject [ 72 | request_seq := anObject 73 | ] 74 | 75 | { #category : 'accessing' } 76 | DAPResponse >> success [ 77 | ^ success 78 | ] 79 | 80 | { #category : 'accessing' } 81 | DAPResponse >> success: anObject [ 82 | success := anObject 83 | ] 84 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPScope.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPScope', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'name', 6 | 'variablesReference', 7 | 'expensive' 8 | ], 9 | #category : 'PharoDAP-Types', 10 | #package : 'PharoDAP', 11 | #tag : 'Types' 12 | } 13 | 14 | { #category : 'accessing' } 15 | DAPScope >> asDAPJSON [ 16 | ^ super asDAPJSON 17 | at: #expensive put: self expensive; 18 | at: #name put: self name; 19 | at: #variablesReference put: self variablesReference; 20 | yourself 21 | ] 22 | 23 | { #category : 'accessing' } 24 | DAPScope >> expensive [ 25 | ^ expensive 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPScope >> expensive: anObject [ 30 | expensive := anObject 31 | ] 32 | 33 | { #category : 'accessing' } 34 | DAPScope >> initialize [ 35 | super initialize. 36 | expensive := false 37 | ] 38 | 39 | { #category : 'accessing' } 40 | DAPScope >> name [ 41 | ^ name 42 | ] 43 | 44 | { #category : 'accessing' } 45 | DAPScope >> name: anObject [ 46 | name := anObject 47 | ] 48 | 49 | { #category : 'accessing' } 50 | DAPScope >> variablesReference [ 51 | "the variables of this scope can be retrieved by passing the value of variablesReference to the VariablesRequest." 52 | ^ variablesReference 53 | ] 54 | 55 | { #category : 'accessing' } 56 | DAPScope >> variablesReference: anObject [ 57 | variablesReference := anObject 58 | ] 59 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPScopesResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPScopesResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'scopes' 6 | ], 7 | #category : 'PharoDAP-Structure', 8 | #package : 'PharoDAP', 9 | #tag : 'Structure' 10 | } 11 | 12 | { #category : 'accessing' } 13 | DAPScopesResponse >> asDAPJSON [ 14 | | dic | 15 | self body at: #scopes put: self scopes asArray. 16 | dic := super asDAPJSON. 17 | ^ dic 18 | ] 19 | 20 | { #category : 'accessing' } 21 | DAPScopesResponse >> initialize [ 22 | super initialize. 23 | body := Dictionary new. 24 | scopes := OrderedCollection new. 25 | ] 26 | 27 | { #category : 'accessing' } 28 | DAPScopesResponse >> scopes [ 29 | ^ scopes 30 | ] 31 | 32 | { #category : 'accessing' } 33 | DAPScopesResponse >> scopes: anObject [ 34 | scopes := anObject 35 | ] 36 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPSetBreakpointsResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPSetBreakpointsResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPSetExceptionBreakpointsResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPSetExceptionBreakpointsResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPSource.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPSource', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'name', 6 | 'sourceReference', 7 | 'path' 8 | ], 9 | #category : 'PharoDAP-Types', 10 | #package : 'PharoDAP', 11 | #tag : 'Types' 12 | } 13 | 14 | { #category : 'accessing' } 15 | DAPSource >> asDAPJSON [ 16 | | json | 17 | json:= super asDAPJSON 18 | at: #name put: self name; 19 | at: #sourceReference put: self sourceReference; 20 | yourself. 21 | self path ifNotNil:[ json at:#path put: self path ]. 22 | ^ json 23 | ] 24 | 25 | { #category : 'accessing' } 26 | DAPSource >> name [ 27 | ^ name 28 | ] 29 | 30 | { #category : 'accessing' } 31 | DAPSource >> name: anObject [ 32 | name := anObject 33 | ] 34 | 35 | { #category : 'accessing' } 36 | DAPSource >> path [ 37 | 38 | ^ path 39 | ] 40 | 41 | { #category : 'accessing' } 42 | DAPSource >> path: anObject [ 43 | 44 | path := anObject 45 | ] 46 | 47 | { #category : 'accessing' } 48 | DAPSource >> sourceReference [ 49 | ^ sourceReference 50 | ] 51 | 52 | { #category : 'accessing' } 53 | DAPSource >> sourceReference: anObject [ 54 | sourceReference := anObject 55 | ] 56 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPSourceResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPSourceResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | 9 | { #category : 'initialization' } 10 | DAPSourceResponse >> content: string [ 11 | self body at: #content put: string 12 | ] 13 | 14 | { #category : 'initialization' } 15 | DAPSourceResponse >> initialize [ 16 | super initialize. 17 | body := Dictionary new 18 | ] 19 | 20 | { #category : 'initialization' } 21 | DAPSourceResponse >> mimeType: string [ 22 | self body at: #mimeType put: string 23 | ] 24 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPStackFrame.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPStackFrame', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'id', 6 | 'name', 7 | 'line', 8 | 'column', 9 | 'source', 10 | 'endLine', 11 | 'endColumn', 12 | 'instructionPointerReference', 13 | 'moduleId', 14 | 'presentationHint' 15 | ], 16 | #category : 'PharoDAP-Types', 17 | #package : 'PharoDAP', 18 | #tag : 'Types' 19 | } 20 | 21 | { #category : 'initialization' } 22 | DAPStackFrame >> asDAPJSON [ 23 | | dic | 24 | dic := super asDAPJSON 25 | at: #id put: self id; 26 | at: #name put: self name; 27 | at: #line put: self line; 28 | yourself. 29 | self source ifNotNil: [ dic at: #source put: self source asDAPJSON ]. 30 | self column ifNotNil: [ dic at: #column put: self column asDAPJSON ]. 31 | 32 | ^ dic 33 | ] 34 | 35 | { #category : 'accessing' } 36 | DAPStackFrame >> column [ 37 | ^ column 38 | ] 39 | 40 | { #category : 'accessing' } 41 | DAPStackFrame >> column: anObject [ 42 | column := anObject 43 | ] 44 | 45 | { #category : 'accessing' } 46 | DAPStackFrame >> id [ 47 | ^ id 48 | ] 49 | 50 | { #category : 'accessing' } 51 | DAPStackFrame >> id: anObject [ 52 | id := anObject 53 | ] 54 | 55 | { #category : 'initialization' } 56 | DAPStackFrame >> initialize [ 57 | super initialize. 58 | line := 0. 59 | column := 0 60 | ] 61 | 62 | { #category : 'accessing' } 63 | DAPStackFrame >> line [ 64 | ^ line 65 | ] 66 | 67 | { #category : 'accessing' } 68 | DAPStackFrame >> line: anObject [ 69 | line := anObject 70 | ] 71 | 72 | { #category : 'accessing' } 73 | DAPStackFrame >> name [ 74 | ^ name 75 | ] 76 | 77 | { #category : 'accessing' } 78 | DAPStackFrame >> name: anObject [ 79 | name := anObject 80 | ] 81 | 82 | { #category : 'accessing' } 83 | DAPStackFrame >> source [ 84 | ^ source 85 | ] 86 | 87 | { #category : 'accessing' } 88 | DAPStackFrame >> source: anObject [ 89 | source := anObject 90 | ] 91 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPStackTraceResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPStackTraceResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'stackFrames', 6 | 'totalFrames' 7 | ], 8 | #category : 'PharoDAP-Structure', 9 | #package : 'PharoDAP', 10 | #tag : 'Structure' 11 | } 12 | 13 | { #category : 'initialization' } 14 | DAPStackTraceResponse >> asDAPJSON [ 15 | | dic | 16 | self body at: #stackFrames put: self stackFrames asArray. 17 | dic := super asDAPJSON. 18 | ^ dic 19 | ] 20 | 21 | { #category : 'initialization' } 22 | DAPStackTraceResponse >> initialize [ 23 | super initialize. 24 | body := Dictionary new. 25 | stackFrames := OrderedCollection new. 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPStackTraceResponse >> stackFrames [ 30 | ^ stackFrames 31 | ] 32 | 33 | { #category : 'accessing' } 34 | DAPStackTraceResponse >> stackFrames: anObject [ 35 | stackFrames := anObject 36 | ] 37 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPStepInResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPStepInResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPStepOutResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPStepOutResponse', 3 | #superclass : 'DAPResponse', 4 | #category : 'PharoDAP-Structure', 5 | #package : 'PharoDAP', 6 | #tag : 'Structure' 7 | } 8 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPStoppedEvent.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPStoppedEvent', 3 | #superclass : 'DAPEvent', 4 | #instVars : [ 5 | 'description', 6 | 'reason', 7 | 'threadId', 8 | 'preserveFocusHint', 9 | 'text', 10 | 'allThreadsStopped' 11 | ], 12 | #category : 'PharoDAP-Structure', 13 | #package : 'PharoDAP', 14 | #tag : 'Structure' 15 | } 16 | 17 | { #category : 'accessing' } 18 | DAPStoppedEvent >> allThreadsStopped [ 19 | ^ allThreadsStopped ifNil:[ allThreadsStopped := true ] 20 | ] 21 | 22 | { #category : 'accessing' } 23 | DAPStoppedEvent >> allThreadsStopped: anObject [ 24 | allThreadsStopped := anObject 25 | ] 26 | 27 | { #category : 'as yet unclassified' } 28 | DAPStoppedEvent >> asDAPJSON [ 29 | | dic | 30 | self body at: #reason put: self reason. 31 | self body at: #description put: self description printString. 32 | self body at: #threadId put: self threadId. 33 | self body at: #allThreadsStopped put: self allThreadsStopped. 34 | dic := super asDAPJSON. 35 | ^ dic 36 | ] 37 | 38 | { #category : 'accessing' } 39 | DAPStoppedEvent >> description [ 40 | ^ description 41 | ] 42 | 43 | { #category : 'accessing' } 44 | DAPStoppedEvent >> description: anObject [ 45 | description := anObject 46 | ] 47 | 48 | { #category : 'as yet unclassified' } 49 | DAPStoppedEvent >> initialize [ 50 | super initialize. 51 | body := Dictionary new. 52 | event := 'stopped' 53 | ] 54 | 55 | { #category : 'accessing' } 56 | DAPStoppedEvent >> preserveFocusHint [ 57 | ^ preserveFocusHint 58 | ] 59 | 60 | { #category : 'accessing' } 61 | DAPStoppedEvent >> preserveFocusHint: anObject [ 62 | preserveFocusHint := anObject 63 | ] 64 | 65 | { #category : 'accessing' } 66 | DAPStoppedEvent >> reason [ 67 | "'step' | 'breakpoint' | 'exception' | 'pause' | 'entry' | 'goto' 68 | | 'function breakpoint' | 'data breakpoint' | 'instruction breakpoint' 69 | | string" 70 | 71 | ^ reason 72 | ] 73 | 74 | { #category : 'accessing' } 75 | DAPStoppedEvent >> reason: anObject [ 76 | reason := anObject 77 | ] 78 | 79 | { #category : 'accessing' } 80 | DAPStoppedEvent >> text [ 81 | ^ text 82 | ] 83 | 84 | { #category : 'accessing' } 85 | DAPStoppedEvent >> text: anObject [ 86 | text := anObject 87 | ] 88 | 89 | { #category : 'accessing' } 90 | DAPStoppedEvent >> threadId [ 91 | ^ threadId 92 | ] 93 | 94 | { #category : 'accessing' } 95 | DAPStoppedEvent >> threadId: anObject [ 96 | threadId := anObject 97 | ] 98 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPTScope.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPTScope', 3 | #superclass : 'Object', 4 | #instVars : [ 5 | 'scope', 6 | 'inCache' 7 | ], 8 | #category : 'PharoDAP-Types-Extension', 9 | #package : 'PharoDAP', 10 | #tag : 'Types-Extension' 11 | } 12 | 13 | { #category : 'as yet unclassified' } 14 | DAPTScope >> getDAPVariablesInContent: context [ 15 | | localVars bindingVars | 16 | 17 | bindingVars := OrderedDictionary new. 18 | (context receiver respondsTo:#bindings) ifTrue:[ 19 | context receiver bindings associationsDo:[ : aBindingVar | 20 | 21 | self inCache 22 | at: aBindingVar value hash 23 | put: 24 | {(#context -> context). 25 | (#scope 26 | -> 27 | (DAPTVariableScope new 28 | scope: aBindingVar value; 29 | inCache: self inCache; 30 | yourself))} asDictionary. 31 | bindingVars at:aBindingVar key put: (DAPVariable new 32 | name: aBindingVar key; 33 | value: ([aBindingVar value printString] on:Exception do:['?']); 34 | variablesReference: 35 | (aBindingVar value class allInstVarNames 36 | ifEmpty: [ 0 ] 37 | ifNotEmpty: [ aBindingVar value hash ]); 38 | yourself) 39 | ] ]. 40 | localVars :=self scope tempVars 41 | collect: [ :tempVar | 42 | | result | 43 | result := tempVar readFromLocalContext: context. 44 | self inCache 45 | at: tempVar hash 46 | put: 47 | {(#context -> context). 48 | (#scope 49 | -> 50 | (DAPTVariableScope new 51 | scope: result; 52 | inCache: self inCache; 53 | yourself))} asDictionary. 54 | 55 | "Create a DAP variable with the variable name and value" 56 | DAPVariable new 57 | name: tempVar name; 58 | value: ([result printString] on:Exception do:['?']); 59 | variablesReference: 60 | (result class allInstVarNames 61 | ifEmpty: [ 0 ] 62 | ifNotEmpty: [ tempVar hash ]); 63 | yourself ]. 64 | ^ localVars addAll: bindingVars;yourself 65 | 66 | 67 | 68 | 69 | ] 70 | 71 | { #category : 'accessing' } 72 | DAPTScope >> inCache [ 73 | ^ inCache 74 | ] 75 | 76 | { #category : 'accessing' } 77 | DAPTScope >> inCache: anObject [ 78 | inCache := anObject 79 | ] 80 | 81 | { #category : 'accessing' } 82 | DAPTScope >> scope [ 83 | ^ scope 84 | ] 85 | 86 | { #category : 'accessing' } 87 | DAPTScope >> scope: anObject [ 88 | scope := anObject 89 | ] 90 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPTVariableScope.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPTVariableScope', 3 | #superclass : 'DAPTScope', 4 | #category : 'PharoDAP-Types-Extension', 5 | #package : 'PharoDAP', 6 | #tag : 'Types-Extension' 7 | } 8 | 9 | { #category : 'as yet unclassified' } 10 | DAPTVariableScope >> getDAPVariablesInContent: context [ 11 | ^ self scope class allInstVarNames 12 | collectWithIndex: [ :ivName :index | 13 | | result | 14 | result := context object: self scope instVarAt: index. 15 | self inCache 16 | at: result hash 17 | put: 18 | {(#context -> context). 19 | (#scope 20 | -> 21 | (self class new 22 | scope: result; 23 | inCache: self inCache; 24 | yourself))} asDictionary. 25 | DAPVariable new 26 | name: ivName; 27 | value: ([result printString] on:Exception do:['?']); 28 | variablesReference: 29 | (result class allInstVarNames 30 | ifEmpty: [ 0 ] 31 | ifNotEmpty: [ result hash ]); 32 | yourself ] 33 | ] 34 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPTerminatedEvent.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Please comment me using the following template inspired by Class Responsibility Collaborator (CRC) design: 3 | 4 | For the Class part: State a one line summary. For example, ""I represent a paragraph of text"". 5 | 6 | For the Responsibility part: Three sentences about my main responsibilities - what I do, what I know. 7 | 8 | For the Collaborators Part: State my main collaborators and one line about how I interact with them. 9 | 10 | Public API and Key Messages 11 | 12 | - message one 13 | - message two 14 | - (for bonus points) how to create instances. 15 | 16 | One simple example is simply gorgeous. 17 | 18 | Internal Representation and Key Implementation Points. 19 | 20 | 21 | Implementation Points 22 | " 23 | Class { 24 | #name : 'DAPTerminatedEvent', 25 | #superclass : 'DAPEvent', 26 | #category : 'PharoDAP-Structure', 27 | #package : 'PharoDAP', 28 | #tag : 'Structure' 29 | } 30 | 31 | { #category : 'as yet unclassified' } 32 | DAPTerminatedEvent >> initialize [ 33 | super initialize. 34 | event := 'terminated' 35 | ] 36 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPThread.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPThread', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'id', 6 | 'name' 7 | ], 8 | #category : 'PharoDAP-Types', 9 | #package : 'PharoDAP', 10 | #tag : 'Types' 11 | } 12 | 13 | { #category : 'converting' } 14 | DAPThread >> asDAPJSON [ 15 | ^ super asDAPJSON 16 | at: #id put: self id; 17 | at: #name put: self name; 18 | yourself 19 | ] 20 | 21 | { #category : 'accessing' } 22 | DAPThread >> id [ 23 | ^ id 24 | ] 25 | 26 | { #category : 'accessing' } 27 | DAPThread >> id: anObject [ 28 | id := anObject 29 | ] 30 | 31 | { #category : 'accessing' } 32 | DAPThread >> name [ 33 | ^ name 34 | ] 35 | 36 | { #category : 'accessing' } 37 | DAPThread >> name: anObject [ 38 | name := anObject 39 | ] 40 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPThreadsResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPThreadsResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'threads' 6 | ], 7 | #category : 'PharoDAP-Structure', 8 | #package : 'PharoDAP', 9 | #tag : 'Structure' 10 | } 11 | 12 | { #category : 'initialization' } 13 | DAPThreadsResponse >> asDAPJSON [ 14 | | dic | 15 | self body at: #threads put: threads asArray. 16 | dic := super asDAPJSON. 17 | ^ dic 18 | ] 19 | 20 | { #category : 'initialization' } 21 | DAPThreadsResponse >> initialize [ 22 | super initialize. 23 | body := Dictionary new. 24 | threads := OrderedCollection new. 25 | ] 26 | 27 | { #category : 'accessing' } 28 | DAPThreadsResponse >> threads [ 29 | ^ threads 30 | ] 31 | 32 | { #category : 'accessing' } 33 | DAPThreadsResponse >> threads: anObject [ 34 | threads := anObject 35 | ] 36 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPVariable.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPVariable', 3 | #superclass : 'DAPJsonableObject', 4 | #instVars : [ 5 | 'name', 6 | 'value', 7 | 'variablesReference' 8 | ], 9 | #category : 'PharoDAP-Types', 10 | #package : 'PharoDAP', 11 | #tag : 'Types' 12 | } 13 | 14 | { #category : 'accessing' } 15 | DAPVariable >> asDAPJSON [ 16 | ^ super asDAPJSON 17 | at: #name put: self name; 18 | at: #value put: self value1; 19 | at: #variablesReference put: self variablesReference; 20 | yourself 21 | ] 22 | 23 | { #category : 'accessing' } 24 | DAPVariable >> name [ 25 | ^ name 26 | ] 27 | 28 | { #category : 'accessing' } 29 | DAPVariable >> name: anObject [ 30 | name := anObject 31 | ] 32 | 33 | { #category : 'accessing' } 34 | DAPVariable >> value1 [ 35 | ^ value 36 | ] 37 | 38 | { #category : 'accessing' } 39 | DAPVariable >> value: anObject [ 40 | value := anObject 41 | ] 42 | 43 | { #category : 'accessing' } 44 | DAPVariable >> variablesReference [ 45 | ^ variablesReference 46 | ] 47 | 48 | { #category : 'accessing' } 49 | DAPVariable >> variablesReference: anObject [ 50 | variablesReference := anObject 51 | ] 52 | -------------------------------------------------------------------------------- /src/PharoDAP/DAPVariablesResponse.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'DAPVariablesResponse', 3 | #superclass : 'DAPResponse', 4 | #instVars : [ 5 | 'variables' 6 | ], 7 | #category : 'PharoDAP-Structure', 8 | #package : 'PharoDAP', 9 | #tag : 'Structure' 10 | } 11 | 12 | { #category : 'accessing' } 13 | DAPVariablesResponse >> asDAPJSON [ 14 | | dic | 15 | self body at: #variables put: variables asArray. 16 | dic := super asDAPJSON. 17 | ^ dic 18 | ] 19 | 20 | { #category : 'initialization' } 21 | DAPVariablesResponse >> initialize [ 22 | super initialize. 23 | body := Dictionary new. 24 | variables := OrderedCollection new. 25 | ] 26 | 27 | { #category : 'accessing' } 28 | DAPVariablesResponse >> variables [ 29 | ^ variables 30 | ] 31 | 32 | { #category : 'accessing' } 33 | DAPVariablesResponse >> variables: anObject [ 34 | variables := anObject 35 | ] 36 | -------------------------------------------------------------------------------- /src/PharoDAP/Dictionary.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'Dictionary' } 2 | 3 | { #category : '*PharoDAP' } 4 | Dictionary >> asDAPJSON [ 5 | ^ (self associations collect: [ :assoc | 6 | self assert: assoc key isString. 7 | assoc key -> assoc value asDAPJSON ]) asDictionary 8 | ] 9 | -------------------------------------------------------------------------------- /src/PharoDAP/Error.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'Error' } 2 | 3 | { #category : '*PharoDAP' } 4 | Error >> asDAPResponse [ 5 | ^ { } asDictionary 6 | ] 7 | -------------------------------------------------------------------------------- /src/PharoDAP/Integer.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'Integer' } 2 | 3 | { #category : '*PharoDAP' } 4 | Integer >> asDAPJSON [ 5 | ^ self 6 | ] 7 | -------------------------------------------------------------------------------- /src/PharoDAP/OCExtraBindingScope.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'OCExtraBindingScope' } 2 | 3 | { #category : '*PharoDAP' } 4 | OCExtraBindingScope >> scopeLevel [ 5 | ^ 0 6 | ] 7 | -------------------------------------------------------------------------------- /src/PharoDAP/String.extension.st: -------------------------------------------------------------------------------- 1 | Extension { #name : 'String' } 2 | 3 | { #category : '*PharoDAP' } 4 | String >> asDAPJSON [ 5 | ^ self 6 | ] 7 | 8 | { #category : '*PharoDAP' } 9 | String >> toLineColumn: position [ 10 | "given a position, return a dictionnary with the line and column of the cursor at this position" 11 | 12 | | copy | 13 | copy := (self copyFrom: 1 to: position) lines. 14 | ^ {(#line -> copy size). 15 | (#column -> copy last size)} asDictionary 16 | ] 17 | -------------------------------------------------------------------------------- /src/PharoDAP/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : 'PharoDAP' } 2 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/PLCAnswerProcessor.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCAnswerProcessor', 3 | #superclass : 'Object', 4 | #instVars : [ 5 | 'answerHandlers', 6 | 'client' 7 | ], 8 | #category : 'PharoLanguageClient', 9 | #package : 'PharoLanguageClient' 10 | } 11 | 12 | { #category : 'instance creation' } 13 | PLCAnswerProcessor class >> for: aTPLCClient [ 14 | 15 | ^ self new 16 | client: aTPLCClient; 17 | yourself 18 | ] 19 | 20 | { #category : 'adding' } 21 | PLCAnswerProcessor >> addHandlerFor: aRequest [ 22 | 23 | (Pragma allNamed: #jrpc: in: client class) 24 | detect: [ :pragma | 25 | (pragma argumentNamed: #jrpc:) = aRequest method ] 26 | ifFound: [ :pragma | 27 | self answerHandlers 28 | at: aRequest id 29 | put: (PLCMessageSendHandler new 30 | receiver: client; 31 | methodName: pragma arguments first; 32 | messageSelector: pragma methodSelector; 33 | originRequest: aRequest; 34 | yourself) ] 35 | ] 36 | 37 | { #category : 'accessing' } 38 | PLCAnswerProcessor >> answerHandlers [ 39 | 40 | ^ answerHandlers 41 | ] 42 | 43 | { #category : 'accessing' } 44 | PLCAnswerProcessor >> answerHandlers: anObject [ 45 | 46 | answerHandlers := anObject 47 | ] 48 | 49 | { #category : 'adding' } 50 | PLCAnswerProcessor >> cancelRequestBefore: textDocumentIdentifier [ 51 | 52 | self answerHandlers 53 | select: [ :handler | 54 | handler originRequest params 55 | at: #textDocument 56 | ifPresent: [ :td | 57 | (td at: #version) < textDocumentIdentifier version ] 58 | ifAbsent: [ false ] ] 59 | thenDo: [ :handler | 60 | self client sendCancelRequest: handler originRequest id. 61 | self removeHandlerWithId: handler originRequest id ] 62 | ] 63 | 64 | { #category : 'accessing' } 65 | PLCAnswerProcessor >> client [ 66 | 67 | ^ client 68 | ] 69 | 70 | { #category : 'accessing' } 71 | PLCAnswerProcessor >> client: anObject [ 72 | 73 | client := anObject 74 | ] 75 | 76 | { #category : 'adding' } 77 | PLCAnswerProcessor >> handle: aRequest [ 78 | 79 | | serializedRequest | 80 | serializedRequest := STONJSON fromString: aRequest. 81 | serializedRequest 82 | at: #id 83 | ifPresent: [ :id | 84 | self answerHandlers at: id ifPresent: [ :h | 85 | self answerHandlers removeKey: id. 86 | h executeWithArguments: (serializedRequest at: #result) ] ] 87 | ifAbsent: [ 88 | (Pragma allNamed: #jrpc: in: client class) 89 | detect: [ :pragma | 90 | (pragma argumentNamed: #jrpc:) = (serializedRequest at: #method) ] 91 | ifFound: [ :pragma | 92 | PLSMessageSendHandler new 93 | receiver: client; 94 | methodName: pragma arguments first; 95 | messageSelector: pragma methodSelector; 96 | executeWithArguments: (serializedRequest at: #params) ] 97 | ifNone: [ ] ] 98 | ] 99 | 100 | { #category : 'initialization' } 101 | PLCAnswerProcessor >> initialize [ 102 | 103 | super initialize. 104 | self answerHandlers: Dictionary new 105 | ] 106 | 107 | { #category : 'adding' } 108 | PLCAnswerProcessor >> removeHandlerWithId: anID [ 109 | 110 | self answerHandlers removeKey: anID ifAbsent: [ ] 111 | ] 112 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/PLCContext.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCContext', 3 | #superclass : 'Object', 4 | #instVars : [ 5 | 'textItems' 6 | ], 7 | #category : 'PharoLanguageClient', 8 | #package : 'PharoLanguageClient' 9 | } 10 | 11 | { #category : 'initialization' } 12 | PLCContext >> initialize [ 13 | 14 | super initialize. 15 | textItems := Dictionary new 16 | ] 17 | 18 | { #category : 'initialization' } 19 | PLCContext >> removeTextItem: aURI [ 20 | 21 | ^ self textItems removeKey: aURI 22 | ] 23 | 24 | { #category : 'initialization' } 25 | PLCContext >> textItem: aURI [ 26 | 27 | ^ self textItems at: aURI 28 | ] 29 | 30 | { #category : 'initialization' } 31 | PLCContext >> textItem: aURI put: aTextItem [ 32 | 33 | ^ self textItems at: aURI put: aTextItem 34 | ] 35 | 36 | { #category : 'accessing' } 37 | PLCContext >> textItems [ 38 | 39 | ^ textItems 40 | ] 41 | 42 | { #category : 'accessing' } 43 | PLCContext >> textItems: anObject [ 44 | 45 | textItems := anObject 46 | ] 47 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/PLCMessageSendHandler.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCMessageSendHandler', 3 | #superclass : 'JRPCMessageSendHandler', 4 | #instVars : [ 5 | 'originRequest' 6 | ], 7 | #category : 'PharoLanguageClient', 8 | #package : 'PharoLanguageClient' 9 | } 10 | 11 | { #category : 'parameters-checking' } 12 | PLCMessageSendHandler >> checkParametersForRequest: aJRPCRequestObject [ 13 | 14 | aJRPCRequestObject params ifNil: [ 15 | self parametersCount = 0 ifFalse: [ JRPCInvalidParameters signal ] ]. 16 | 17 | (aJRPCRequestObject params ifNil: [ #( ) ]) size 18 | <= self parametersCount ifFalse: [ JRPCInvalidParameters signal ]. 19 | 20 | (aJRPCRequestObject params isDictionary or: [ 21 | aJRPCRequestObject params isNil ]) ifFalse: [ 22 | JRPCInvalidParameters signal ] 23 | ] 24 | 25 | { #category : 'evaluation' } 26 | PLCMessageSendHandler >> executeWithArguments: anArrayOrDictionary [ 27 | 28 | | arguments | 29 | arguments := anArrayOrDictionary. 30 | 31 | anArrayOrDictionary ifNil: [ arguments := #( ) ]. 32 | 33 | anArrayOrDictionary isDictionary ifTrue: [ 34 | self originRequest ifNotNil: [ :ori | 35 | anArrayOrDictionary at: #originRequest put: ori ]. 36 | arguments := OrderedCollection new. 37 | self parametersNames do: [ :name | 38 | arguments add: (anArrayOrDictionary at: name ifAbsent: [ nil ]) ]. 39 | arguments := arguments asArray ]. 40 | 41 | anArrayOrDictionary isArray ifTrue: [ 42 | arguments := self originRequest 43 | ifNotNil: [ :ori | 44 | { 45 | anArrayOrDictionary. 46 | ori } ] 47 | ifNil: [ { anArrayOrDictionary } ] ]. 48 | 49 | 50 | ^ self send: self messageSelector to: self receiver with: arguments 51 | ] 52 | 53 | { #category : 'accessing' } 54 | PLCMessageSendHandler >> originRequest [ 55 | 56 | ^ originRequest 57 | ] 58 | 59 | { #category : 'accessing' } 60 | PLCMessageSendHandler >> originRequest: anObject [ 61 | 62 | originRequest := anObject 63 | ] 64 | 65 | { #category : 'accessing' } 66 | PLCMessageSendHandler >> parametersNames [ 67 | 68 | ^ (self receiver class lookupSelector: self messageSelector) 69 | argumentNames 70 | ] 71 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/PLCPythonServerConfigurationRunner.class.st: -------------------------------------------------------------------------------- 1 | " 2 | # Python server 3 | 4 | ## Installation 5 | 6 | First install the python server locally with 7 | 8 | ```sh 9 | pip install python-lsp-server 10 | pip install 'python-lsp-server[websockets]' 11 | ``` 12 | " 13 | Class { 14 | #name : 'PLCPythonServerConfigurationRunner', 15 | #superclass : 'PLCServerConfigurationRunner', 16 | #category : 'PharoLanguageClient', 17 | #package : 'PharoLanguageClient' 18 | } 19 | 20 | { #category : 'as yet unclassified' } 21 | PLCPythonServerConfigurationRunner class >> supportedLanguages [ 22 | 23 | ^ { #python } 24 | ] 25 | 26 | { #category : 'testing' } 27 | PLCPythonServerConfigurationRunner >> isTCPHost [ 28 | 29 | ^ false 30 | ] 31 | 32 | { #category : 'as yet unclassified' } 33 | PLCPythonServerConfigurationRunner >> visitWindows: aPlatform [ 34 | 35 | ^ LibC runCommand: (String streamContents: [ :stream | 36 | stream << 'start powershell -noexit -noprofil -command "& { '. 37 | stream << 'pylsp --tcp -vv --port '. 38 | self tcpPort printOn: stream. 39 | stream << ' }"' ]) 40 | ] 41 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/PLCServerConfigurationRunner.class.st: -------------------------------------------------------------------------------- 1 | " 2 | Use me to start already installed server from pharo (usefull when creating a client) 3 | " 4 | Class { 5 | #name : 'PLCServerConfigurationRunner', 6 | #superclass : 'OSPlatformVisitor', 7 | #instVars : [ 8 | 'tcpPort' 9 | ], 10 | #category : 'PharoLanguageClient', 11 | #package : 'PharoLanguageClient' 12 | } 13 | 14 | { #category : 'as yet unclassified' } 15 | PLCServerConfigurationRunner class >> newFor: aProgrammingLanguageString [ 16 | 17 | ^ (self allSubclasses detect: [ :clazz | 18 | clazz supportedLanguages includes: aProgrammingLanguageString ]) 19 | new 20 | ] 21 | 22 | { #category : 'as yet unclassified' } 23 | PLCServerConfigurationRunner class >> supportedLanguages [ 24 | 25 | ^ self subclassResponsibility 26 | ] 27 | 28 | { #category : 'testing' } 29 | PLCServerConfigurationRunner >> isTCPHost [ 30 | ^ self subclassResponsibility 31 | ] 32 | 33 | { #category : 'accessing' } 34 | PLCServerConfigurationRunner >> tcpPort [ 35 | 36 | ^ tcpPort 37 | ] 38 | 39 | { #category : 'accessing' } 40 | PLCServerConfigurationRunner >> tcpPort: anObject [ 41 | 42 | tcpPort := anObject 43 | ] 44 | -------------------------------------------------------------------------------- /src/PharoLanguageClient/package.st: -------------------------------------------------------------------------------- 1 | Package { #name : 'PharoLanguageClient' } 2 | -------------------------------------------------------------------------------- /src/PharoLanguageClientLocal/PLCClient.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCClient', 3 | #superclass : 'Object', 4 | #traits : 'TPLCClient', 5 | #classTraits : 'TPLCClient classTrait', 6 | #category : 'PharoLanguageClientLocal', 7 | #package : 'PharoLanguageClientLocal' 8 | } 9 | 10 | { #category : 'plp - answerLoop' } 11 | PLCClient >> answerLoopPriority [ 12 | 13 | ^ answerLoopPriority ifNil: [ 14 | answerLoopPriority := Processor userBackgroundPriority ] 15 | ] 16 | 17 | { #category : 'lsp - symbol' } 18 | PLCClient >> clientSymbol: items fromRequest: originRequest [ 19 | 20 | 21 | | originUri | 22 | originUri := originRequest params at: #textDocument at: #uri. 23 | (context textItem: originUri) applySymbols: 24 | (items collect: [ :item | 25 | | symbol | 26 | symbol := PLSDocumentSymbol new. 27 | symbol name: (item at: #name). 28 | item at: #detail ifPresent: [ :detail | symbol detail: detail ]. 29 | symbol kind: (item at: #kind). 30 | symbol range: (PLSRange 31 | start: ((item at: #location at: #range) at: #start) 32 | end: ((item at: #location at: #range) at: #end)) ]) 33 | ] 34 | 35 | { #category : 'api' } 36 | PLCClient >> initialize [ 37 | 38 | super initialize 39 | ] 40 | -------------------------------------------------------------------------------- /src/PharoLanguageClientLocal/PLCCodePresenter.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCCodePresenter', 3 | #superclass : 'SpTextPresenter', 4 | #instVars : [ 5 | 'language', 6 | 'plcClient', 7 | 'version' 8 | ], 9 | #category : 'PharoLanguageClientLocal-CodePresenter', 10 | #package : 'PharoLanguageClientLocal', 11 | #tag : 'CodePresenter' 12 | } 13 | 14 | { #category : 'accessing' } 15 | PLCCodePresenter >> applySymbols: listOfSymbols [ 16 | 17 | | skinnableText | 18 | skinnableText := self text asText. 19 | listOfSymbols do: [ :symbol | 20 | skinnableText 21 | addAttribute: (TextColor new color: Color blue) 22 | from: (self text plsToPosition: symbol range start) +1 23 | to: (self text plsToPosition: symbol range end) ]. 24 | ] 25 | 26 | { #category : 'initialization - deprecated' } 27 | PLCCodePresenter >> initializePresenter [ 28 | 29 | version := 0. 30 | language := 'python'. 31 | self startClient. 32 | plcClient 33 | sendDidOpenTextDocument: (PLPTextDocumentItem new 34 | uri: self plpURI; 35 | languageId: self language; 36 | version: version; 37 | text: '') 38 | for: self. 39 | self whenTextChangedDo: [ :text2 | 40 | version := version + 1. 41 | plcClient 42 | sendDidChangeTextDocument: self versionedTextDocumentIdentifier 43 | withChanges: { (PLPTextDocumentContentChangeEvent new 44 | text: self text asString; 45 | yourself) }. 46 | plcClient sendTextDocumentSymbol: 47 | self versionedTextDocumentIdentifier ] 48 | ] 49 | 50 | { #category : 'accessing' } 51 | PLCCodePresenter >> language [ 52 | 53 | ^ language 54 | ] 55 | 56 | { #category : 'accessing' } 57 | PLCCodePresenter >> language: anObject [ 58 | 59 | language := anObject 60 | ] 61 | 62 | { #category : 'initialization' } 63 | PLCCodePresenter >> plpURI [ 64 | 65 | ^ 'plcCodePresenter/' , self identityHash printString 66 | ] 67 | 68 | { #category : 'initialization' } 69 | PLCCodePresenter >> startClient [ 70 | 71 | plcClient := PLCClient new. 72 | plcClient language: #python. 73 | plcClient clientInit. 74 | plcClient start 75 | ] 76 | 77 | { #category : 'initialization - deprecated' } 78 | PLCCodePresenter >> versionedTextDocumentIdentifier [ 79 | 80 | ^ PLSVersionedTextDocumentIdentifier new 81 | uri: self plpURI; 82 | version: version; 83 | yourself 84 | ] 85 | 86 | { #category : 'initialization' } 87 | PLCCodePresenter >> windowIsClosing [ 88 | 89 | plcClient stop 90 | ] 91 | -------------------------------------------------------------------------------- /src/PharoLanguageClientLocal/PLCLRubScrolledTextMorph.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCLRubScrolledTextMorph', 3 | #superclass : 'SpRubScrolledTextMorph', 4 | #classTraits : 'TPLCClient classTrait', 5 | #instVars : [ 6 | 'version' 7 | ], 8 | #category : 'PharoLanguageClientLocal-GraphicalStack', 9 | #package : 'PharoLanguageClientLocal', 10 | #tag : 'GraphicalStack' 11 | } 12 | 13 | { #category : 'accessing' } 14 | PLCLRubScrolledTextMorph >> beForSmalltalkScripting [ 15 | 16 | self textArea beForSmalltalkScripting. 17 | self textArea shoutStyler styler: PLCLTextStyler new. 18 | self textArea font: StandardFonts codeFont 19 | ] 20 | 21 | { #category : 'lsp - completion' } 22 | PLCLRubScrolledTextMorph >> resetInlineCompletion [ 23 | 24 | self textArea setTextWith: self textWithoutGhost 25 | ] 26 | 27 | { #category : 'lsp - completion' } 28 | PLCLRubScrolledTextMorph >> setInlineCompletionWith: aText [ 29 | 30 | self setTextWith: (self textWithoutGhost append: (aText asText 31 | addAttribute: TextGhost new; 32 | yourself)) 33 | ] 34 | 35 | { #category : 'lsp - completion' } 36 | PLCLRubScrolledTextMorph >> textWithoutGhost [ 37 | 38 | ^ self getText withIndexSelect: [ :val :idx | 39 | (self getText runs at: idx) noneSatisfy: [ :run | 40 | run isKindOf: TextGhost ] ] 41 | ] 42 | -------------------------------------------------------------------------------- /src/PharoLanguageClientLocal/PLCLTextStyler.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCLTextStyler', 3 | #superclass : 'SHRBTextStyler', 4 | #category : 'PharoLanguageClientLocal-GraphicalStack', 5 | #package : 'PharoLanguageClientLocal', 6 | #tag : 'GraphicalStack' 7 | } 8 | 9 | { #category : 'attributes' } 10 | PLCLTextStyler class >> formatIncompleteIdentifiers [ 11 | ^ SHRBTextStyler formatIncompleteIdentifiers 12 | ] 13 | 14 | { #category : 'attributes' } 15 | PLCLTextStyler class >> styleTable [ 16 | ^ SHRBTextStyler styleTable 17 | ] 18 | 19 | { #category : 'attributes' } 20 | PLCLTextStyler class >> textAttributesByPixelHeight [ 21 | ^ SHRBTextStyler textAttributesByPixelHeight 22 | ] 23 | 24 | { #category : 'styling' } 25 | PLCLTextStyler >> style: aText [ 26 | 27 | aText ifEmpty: [ ^ self ]. 28 | stylingEnabled ifFalse: [ ^ self ]. 29 | text := aText copy. 30 | self privateStyle: text. 31 | self 32 | addAttributesFrom: aText runs 33 | satisfying: [ :each | each isKindOf: TextGhost ] 34 | to: text. 35 | view ifNotNil: [ :view2 | view2 stylerStyled: text ] 36 | ] 37 | -------------------------------------------------------------------------------- /src/PharoLanguageClientLocal/PLCLocalClient.class.st: -------------------------------------------------------------------------------- 1 | Class { 2 | #name : 'PLCLocalClient', 3 | #superclass : 'Object', 4 | #traits : 'TPLCClient', 5 | #classTraits : 'TPLCClient classTrait', 6 | #classInstVars : [ 7 | 'default' 8 | ], 9 | #category : 'PharoLanguageClientLocal', 10 | #package : 'PharoLanguageClientLocal' 11 | } 12 | 13 | { #category : 'accessing' } 14 | PLCLocalClient class >> default [ 15 | 16 | ^ default ifNil: [ default := self new ] 17 | ] 18 | 19 | { #category : 'accessing' } 20 | PLCLocalClient class >> default: aPLCClient [ 21 | 22 | default := aPLCClient 23 | ] 24 | 25 | { #category : 'accessing' } 26 | PLCLocalClient class >> initialize [ 27 | 28 | Smalltalk addToStartUpList: self. 29 | self reset 30 | ] 31 | 32 | { #category : 'accessing' } 33 | PLCLocalClient class >> inspect [ 34 | 35 |