From 983d0699c238160f4109c39dc22b0662ac9d4215 Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Wed, 3 Aug 2022 10:01:02 +0200 Subject: [PATCH 1/8] Add CI workflow to lint and check formatting of Go code On every push and pull request that affects relevant files, check the Go module for: - Common detectable errors in the code. - Use of outdated APIs - Code style violations - Code formatting inconsistency - Misconfiguration --- .github/workflows/check-go-task.yml | 223 ++++++++++++++++++++++++++++ README.md | 1 + Taskfile.yml | 74 ++++----- 3 files changed, 262 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/check-go-task.yml diff --git a/.github/workflows/check-go-task.yml b/.github/workflows/check-go-task.yml new file mode 100644 index 0000000..844629e --- /dev/null +++ b/.github/workflows/check-go-task.yml @@ -0,0 +1,223 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-task.md +name: Check Go + +env: + # See: https://github.com/actions/setup-go/tree/main#supported-version-syntax + GO_VERSION: "1.18.3" + +# See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows +on: + create: + push: + paths: + - ".github/workflows/check-go-task.ya?ml" + - "Taskfile.ya?ml" + - "**/go.mod" + - "**/go.sum" + - "**.go" + pull_request: + paths: + - ".github/workflows/check-go-task.ya?ml" + - "Taskfile.ya?ml" + - "**/go.mod" + - "**/go.sum" + - "**.go" + schedule: + # Run periodically to catch breakage caused by external changes. + - cron: "0 7 * * WED" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + outputs: + result: ${{ steps.determination.outputs.result }} + steps: + - name: Determine if the rest of the workflow should run + id: determination + run: | + RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" + # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. + if [[ + "${{ github.event_name }}" != "create" || + "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX + ]]; then + # Run the other jobs. + RESULT="true" + else + # There is no need to run the other jobs. + RESULT="false" + fi + + echo "::set-output name=result::$RESULT" + + check-errors: + name: check-errors (${{ matrix.module.path }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + module: + - path: ./ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Check for errors + env: + GO_MODULE_PATH: ${{ matrix.module.path }} + run: task go:vet + + check-outdated: + name: check-outdated (${{ matrix.module.path }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + module: + - path: ./ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Modernize usages of outdated APIs + env: + GO_MODULE_PATH: ${{ matrix.module.path }} + run: task go:fix + + - name: Check if any fixes were needed + run: git diff --color --exit-code + + check-style: + name: check-style (${{ matrix.module.path }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + module: + - path: ./ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Install golint + run: go install golang.org/x/lint/golint@latest + + - name: Check style + env: + GO_MODULE_PATH: ${{ matrix.module.path }} + run: task --silent go:lint + + check-formatting: + name: check-formatting (${{ matrix.module.path }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + module: + - path: ./ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Format code + env: + GO_MODULE_PATH: ${{ matrix.module.path }} + run: task go:format + + - name: Check formatting + run: git diff --color --exit-code + + check-config: + name: check-config (${{ matrix.module.path }}) + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + module: + - path: ./ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Run go mod tidy + working-directory: ${{ matrix.module.path }} + run: go mod tidy + + - name: Check whether any tidying was needed + run: git diff --color --exit-code diff --git a/README.md b/README.md index 5af746e..c915192 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ # Arduino Language Server [![Check Taskfiles status](https://github.com/arduino/arduino-language-server/actions/workflows/check-taskfiles.yml/badge.svg)](https://github.com/arduino/arduino-language-server/actions/workflows/check-taskfiles.yml) +[![Check Go status](https://github.com/arduino/arduino-language-server/actions/workflows/check-go-task.yml/badge.svg)](https://github.com/arduino/arduino-language-server/actions/workflows/check-go-task.yml) The **Arduino Language Server** is the tool that powers the autocompletion of the new [Arduino IDE 2][arduino-ide-repo]. It implements the standard [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) so it can be used with other IDEs as well. diff --git a/Taskfile.yml b/Taskfile.yml index c6c6547..42aac29 100755 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -3,6 +3,44 @@ version: "3" includes: dist: ./DistTasks.yml +vars: + PROJECT_NAME: "arduino-language-server" + DIST_DIR: "dist" + # Path of the project's primary Go module: + DEFAULT_GO_MODULE_PATH: ./ + DEFAULT_GO_PACKAGES: + sh: | + echo $(cd {{default "./" .GO_MODULE_PATH}} && go list ./... | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"') + # build vars + COMMIT: + sh: echo "$(git log --no-show-signature -n 1 --format=%h)" + TIMESTAMP: + sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + TIMESTAMP_SHORT: + sh: echo "{{now | date "20060102"}}" + TAG: + sh: echo "$(git tag --points-at=HEAD 2> /dev/null | head -n1)" + VERSION: "{{if .NIGHTLY}}nightly-{{.TIMESTAMP_SHORT}}{{else if .TAG}}{{.TAG}}{{else}}{{.PACKAGE_NAME_PREFIX}}git-snapshot{{end}}" + CONFIGURATION_PACKAGE: "github.com/arduino/arduino-language-server/version" + LDFLAGS: >- + -ldflags + ' + -X {{.CONFIGURATION_PACKAGE}}.versionString={{.VERSION}} + -X {{.CONFIGURATION_PACKAGE}}.commit={{.COMMIT}} + -X {{.CONFIGURATION_PACKAGE}}.date={{.TIMESTAMP}} + ' + # test vars + GOFLAGS: "-timeout 10m -v -coverpkg=./... -covermode=atomic" + TEST_VERSION: "0.0.0-test.preview" + TEST_COMMIT: "deadbeef" + TEST_LDFLAGS: >- + -ldflags + ' + -X {{.CONFIGURATION_PACKAGE}}.versionString={{.TEST_VERSION}} + -X {{.CONFIGURATION_PACKAGE}}.commit={{.TEST_COMMIT}} + -X {{.CONFIGURATION_PACKAGE}}.date={{.TIMESTAMP}} + ' + tasks: docs:generate: desc: Create all generated documentation content @@ -320,39 +358,3 @@ tasks: - task: poetry:install-deps cmds: - poetry run mkdocs serve - -vars: - PROJECT_NAME: "arduino-language-server" - DIST_DIR: "dist" - DEFAULT_GO_PACKAGES: - sh: | - echo $(cd {{default "./" .GO_MODULE_PATH}} && go list ./... | tr '\n' ' ' || echo '"ERROR: Unable to discover Go packages"') - # build vars - COMMIT: - sh: echo "$(git log --no-show-signature -n 1 --format=%h)" - TIMESTAMP: - sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" - TIMESTAMP_SHORT: - sh: echo "{{now | date "20060102"}}" - TAG: - sh: echo "$(git tag --points-at=HEAD 2> /dev/null | head -n1)" - VERSION: "{{if .NIGHTLY}}nightly-{{.TIMESTAMP_SHORT}}{{else if .TAG}}{{.TAG}}{{else}}{{.PACKAGE_NAME_PREFIX}}git-snapshot{{end}}" - CONFIGURATION_PACKAGE: "github.com/arduino/arduino-language-server/version" - LDFLAGS: >- - -ldflags - ' - -X {{.CONFIGURATION_PACKAGE}}.versionString={{.VERSION}} - -X {{.CONFIGURATION_PACKAGE}}.commit={{.COMMIT}} - -X {{.CONFIGURATION_PACKAGE}}.date={{.TIMESTAMP}} - ' - # test vars - GOFLAGS: "-timeout 10m -v -coverpkg=./... -covermode=atomic" - TEST_VERSION: "0.0.0-test.preview" - TEST_COMMIT: "deadbeef" - TEST_LDFLAGS: >- - -ldflags - ' - -X {{.CONFIGURATION_PACKAGE}}.versionString={{.TEST_VERSION}} - -X {{.CONFIGURATION_PACKAGE}}.commit={{.TEST_COMMIT}} - -X {{.CONFIGURATION_PACKAGE}}.date={{.TIMESTAMP}} - ' From c494eeb3cb6efd5c889d816123ff049efc4ffb7d Mon Sep 17 00:00:00 2001 From: Matteo Pologruto Date: Wed, 3 Aug 2022 10:05:32 +0200 Subject: [PATCH 2/8] Fix formatting errors in go files --- ls/builder.go | 6 ++-- ls/ls.go | 56 +++++++++++++++++++++++++---------- ls/ls_ide_to_clang.go | 3 +- ls/lsp_client_clangd.go | 20 ++++++++++++- ls/lsp_logger.go | 55 +++++++++++++++++++++++----------- ls/lsp_server_ide.go | 65 +++++++++++++++++++++++++++++++++++++++-- ls/progress.go | 1 + 7 files changed, 166 insertions(+), 40 deletions(-) diff --git a/ls/builder.go b/ls/builder.go index 6b0bea7..c716e03 100644 --- a/ls/builder.go +++ b/ls/builder.go @@ -32,6 +32,7 @@ type SketchRebuilder struct { mutex sync.Mutex } +// NewSketchBuilder makes a new SketchRebuilder and returns its pointer func NewSketchBuilder(ls *INOLanguageServer) *SketchRebuilder { res := &SketchRebuilder{ trigger: make(chan chan<- bool, 1), @@ -57,6 +58,7 @@ func (ls *INOLanguageServer) triggerRebuild() { ls.sketchRebuilder.TriggerRebuild(nil) } +// TriggerRebuild schedule a sketch rebuild (it will be executed asynchronously) func (r *SketchRebuilder) TriggerRebuild(completed chan<- bool) { r.mutex.Lock() defer r.mutex.Unlock() @@ -207,8 +209,8 @@ func (ls *INOLanguageServer) generateBuildEnvironment(ctx context.Context, fullB Verbose: true, SkipLibrariesDiscovery: !fullBuild, } - compileReqJson, _ := json.MarshalIndent(compileReq, "", " ") - logger.Logf("Running build with: %s", string(compileReqJson)) + compileReqJSON, _ := json.MarshalIndent(compileReq, "", " ") + logger.Logf("Running build with: %s", string(compileReqJSON)) compRespStream, err := client.Compile(context.Background(), compileReq) if err != nil { diff --git a/ls/ls.go b/ls/ls.go index f3b18ed..151b5f9 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -155,6 +155,7 @@ func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, config *Config) *IN return ls } +// InitializeReqFromIDE initializes a new request from the IDE func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) { ls.writeLock(logger, false) ls.sketchRoot = ideParams.RootURI.AsPath() @@ -363,6 +364,7 @@ func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger js return resp, nil } +// ShutdownReqFromIDE executes a shutdown request from the IDE func (ls *INOLanguageServer) ShutdownReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { done := make(chan bool) go func() { @@ -374,6 +376,7 @@ func (ls *INOLanguageServer) ShutdownReqFromIDE(ctx context.Context, logger json return nil } +// TextDocumentCompletionReqFromIDE handles a text document completion request received from the IDE func (ls *INOLanguageServer) TextDocumentCompletionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CompletionParams) (*lsp.CompletionList, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -468,6 +471,7 @@ func (ls *INOLanguageServer) TextDocumentCompletionReqFromIDE(ctx context.Contex return ideCompletionList, nil } +// TextDocumentHoverReqFromIDE handles a text document hover request received from the IDE func (ls *INOLanguageServer) TextDocumentHoverReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.HoverParams) (*lsp.Hover, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -519,6 +523,7 @@ func (ls *INOLanguageServer) TextDocumentHoverReqFromIDE(ctx context.Context, lo return &ideResp, nil } +// TextDocumentSignatureHelpReqFromIDE handles a text document signature help request received from the IDE func (ls *INOLanguageServer) TextDocumentSignatureHelpReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.SignatureHelpParams) (*lsp.SignatureHelp, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -550,6 +555,7 @@ func (ls *INOLanguageServer) TextDocumentSignatureHelpReqFromIDE(ctx context.Con return ideSignatureHelp, nil } +// TextDocumentDefinitionReqFromIDE handles a text document definition request received from the IDE func (ls *INOLanguageServer) TextDocumentDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -594,6 +600,7 @@ func (ls *INOLanguageServer) TextDocumentDefinitionReqFromIDE(ctx context.Contex return ideLocations, ideLocationLinks, nil } +// TextDocumentTypeDefinitionReqFromIDE handles a text document type definition request received from the IDE func (ls *INOLanguageServer) TextDocumentTypeDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.TypeDefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { // XXX: This capability is not advertised in the initialization message (clangd // does not advertise it either, so maybe we should just not implement it) @@ -640,6 +647,7 @@ func (ls *INOLanguageServer) TextDocumentTypeDefinitionReqFromIDE(ctx context.Co return ideLocations, ideLocationLinks, nil } +// TextDocumentImplementationReqFromIDE handles a text document implementation request received from the IDE func (ls *INOLanguageServer) TextDocumentImplementationReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.ImplementationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -684,6 +692,7 @@ func (ls *INOLanguageServer) TextDocumentImplementationReqFromIDE(ctx context.Co return ideLocations, inoLocationLinks, nil } +// TextDocumentDocumentHighlightReqFromIDE handles a text document highlight request received from the IDE func (ls *INOLanguageServer) TextDocumentDocumentHighlightReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -731,6 +740,7 @@ func (ls *INOLanguageServer) TextDocumentDocumentHighlightReqFromIDE(ctx context return ideHighlights, nil } +// TextDocumentDocumentSymbolReqFromIDE handles a text document symbol request received from the IDE func (ls *INOLanguageServer) TextDocumentDocumentSymbolReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, []lsp.SymbolInformation, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -762,13 +772,13 @@ func (ls *INOLanguageServer) TextDocumentDocumentSymbolReqFromIDE(ctx context.Co // Convert response for IDE var ideDocSymbols []lsp.DocumentSymbol if clangDocSymbols != nil { - if s, err := ls.clang2IdeDocumentSymbols(logger, clangDocSymbols, clangParams.TextDocument.URI, ideParams.TextDocument.URI); err != nil { + s, err := ls.clang2IdeDocumentSymbols(logger, clangDocSymbols, clangParams.TextDocument.URI, ideParams.TextDocument.URI) + if err != nil { logger.Logf("Error: %s", err) ls.Close() return nil, nil, &jsonrpc.ResponseError{Code: jsonrpc.ErrorCodesInternalError, Message: err.Error()} - } else { - ideDocSymbols = s } + ideDocSymbols = s } var ideSymbolsInformation []lsp.SymbolInformation if clangSymbolsInformation != nil { @@ -777,6 +787,7 @@ func (ls *INOLanguageServer) TextDocumentDocumentSymbolReqFromIDE(ctx context.Co return ideDocSymbols, ideSymbolsInformation, nil } +// TextDocumentCodeActionReqFromIDE handles a text document code action request received from the IDE func (ls *INOLanguageServer) TextDocumentCodeActionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CodeActionParams) ([]lsp.CommandOrCodeAction, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -846,6 +857,7 @@ func (ls *INOLanguageServer) TextDocumentCodeActionReqFromIDE(ctx context.Contex return ideCommandsOrCodeActions, nil } +// TextDocumentFormattingReqFromIDE handles a text document formatting request received from the IDE func (ls *INOLanguageServer) TextDocumentFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -860,12 +872,12 @@ func (ls *INOLanguageServer) TextDocumentFormattingReqFromIDE(ctx context.Contex } clangURI := clangTextDocument.URI - if cleanup, err := ls.createClangdFormatterConfig(logger, clangURI); err != nil { + cleanup, err := ls.createClangdFormatterConfig(logger, clangURI) + if err != nil { logger.Logf("Error: %s", err) return nil, &jsonrpc.ResponseError{Code: jsonrpc.ErrorCodesInternalError, Message: err.Error()} - } else { - defer cleanup() } + defer cleanup() clangParams := &lsp.DocumentFormattingParams{ WorkDoneProgressParams: ideParams.WorkDoneProgressParams, @@ -894,13 +906,14 @@ func (ls *INOLanguageServer) TextDocumentFormattingReqFromIDE(ctx context.Contex } // Edits may span over multiple .ino files, filter only the edits relative to the currently displayed file - if inoEdits, ok := ideEdits[ideURI]; !ok { + inoEdits, ok := ideEdits[ideURI] + if !ok { return []lsp.TextEdit{}, nil - } else { - return inoEdits, nil } + return inoEdits, nil } +// TextDocumentRangeFormattingReqFromIDE handles a text document range formatting request received from the IDE func (ls *INOLanguageServer) TextDocumentRangeFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -918,12 +931,12 @@ func (ls *INOLanguageServer) TextDocumentRangeFormattingReqFromIDE(ctx context.C Range: clangRange, } - if cleanup, e := ls.createClangdFormatterConfig(logger, clangURI); e != nil { + cleanup, e := ls.createClangdFormatterConfig(logger, clangURI) + if e != nil { logger.Logf("cannot create formatter config file: %v", err) return nil, &jsonrpc.ResponseError{Code: jsonrpc.ErrorCodesInternalError, Message: err.Error()} - } else { - defer cleanup() } + defer cleanup() clangEdits, clangErr, err := ls.Clangd.conn.TextDocumentRangeFormatting(ctx, clangParams) if err != nil { @@ -947,23 +960,26 @@ func (ls *INOLanguageServer) TextDocumentRangeFormattingReqFromIDE(ctx context.C } // Edits may span over multiple .ino files, filter only the edits relative to the currently displayed file - if inoEdits, ok := sketchEdits[ideURI]; !ok { + inoEdits, ok := sketchEdits[ideURI] + if !ok { return []lsp.TextEdit{}, nil - } else { - return inoEdits, nil } + return inoEdits, nil } +// InitializedNotifFromIDE initializes a notification from the IDE func (ls *INOLanguageServer) InitializedNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.InitializedParams) { logger.Logf("Notification is not propagated to clangd") } +// ExitNotifFromIDE logs an exit notification from the IDE func (ls *INOLanguageServer) ExitNotifFromIDE(logger jsonrpc.FunctionLogger) { ls.Clangd.conn.Exit() logger.Logf("Arduino Language Server is shutting down.") os.Exit(0) } +// TextDocumentDidOpenNotifFromIDE handles a notification from the IDE that TextDocument is open func (ls *INOLanguageServer) TextDocumentDidOpenNotifFromIDE(logger jsonrpc.FunctionLogger, ideParam *lsp.DidOpenTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1023,6 +1039,7 @@ func (ls *INOLanguageServer) TextDocumentDidOpenNotifFromIDE(logger jsonrpc.Func } } +// TextDocumentDidChangeNotifFromIDE handles a notification from the IDE that TextDocument changed func (ls *INOLanguageServer) TextDocumentDidChangeNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidChangeTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1119,6 +1136,7 @@ func (ls *INOLanguageServer) TextDocumentDidChangeNotifFromIDE(logger jsonrpc.Fu } } +// TextDocumentDidSaveNotifFromIDE handles a notification from the IDE that TextDocument has been saved func (ls *INOLanguageServer) TextDocumentDidSaveNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidSaveTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1130,6 +1148,7 @@ func (ls *INOLanguageServer) TextDocumentDidSaveNotifFromIDE(logger jsonrpc.Func ls.triggerRebuild() } +// TextDocumentDidCloseNotifFromIDE handles a notification from the IDE that TextDocument has been closed func (ls *INOLanguageServer) TextDocumentDidCloseNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidCloseTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1173,14 +1192,16 @@ func (ls *INOLanguageServer) TextDocumentDidCloseNotifFromIDE(logger jsonrpc.Fun } } +// FullBuildCompletedFromIDE receives a full build from the IDE and copies the results func (ls *INOLanguageServer) FullBuildCompletedFromIDE(logger jsonrpc.FunctionLogger, params *DidCompleteBuildParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) - ls.CopyFullBuildResults(logger, params.BuildOutputUri.AsPath()) + ls.CopyFullBuildResults(logger, params.BuildOutputURI.AsPath()) ls.triggerRebuild() } +// CopyFullBuildResults copies the results of a full build in the LS workspace func (ls *INOLanguageServer) CopyFullBuildResults(logger jsonrpc.FunctionLogger, buildPath *paths.Path) { fromCache := buildPath.Join("libraries.cache") toCache := ls.buildPath.Join("libraries.cache") @@ -1191,6 +1212,7 @@ func (ls *INOLanguageServer) CopyFullBuildResults(logger jsonrpc.FunctionLogger, } } +// PublishDiagnosticsNotifFromClangd publishes a diagnostics if notified from Clangd func (ls *INOLanguageServer) PublishDiagnosticsNotifFromClangd(logger jsonrpc.FunctionLogger, clangParams *lsp.PublishDiagnosticsParams) { if ls.config.DisableRealTimeDiagnostics { logger.Logf("Ignored by configuration") @@ -1271,6 +1293,7 @@ func (ls *INOLanguageServer) PublishDiagnosticsNotifFromClangd(logger jsonrpc.Fu } } +// TextDocumentRenameReqFromIDE handles a request from the IDE to rename TextDocument func (ls *INOLanguageServer) TextDocumentRenameReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.RenameParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, false) defer ls.writeUnlock(logger) @@ -1348,6 +1371,7 @@ func (ls *INOLanguageServer) WindowWorkDoneProgressCreateReqFromClangd(ctx conte return nil } +// SetTraceNotifFromIDE gets a notification from the IDE to Set Trace to parameters func (ls *INOLanguageServer) SetTraceNotifFromIDE(logger jsonrpc.FunctionLogger, params *lsp.SetTraceParams) { logger.Logf("Notification level set to: %s", params.Value) ls.Clangd.conn.SetTrace(params) diff --git a/ls/ls_ide_to_clang.go b/ls/ls_ide_to_clang.go index fc49771..62d6842 100644 --- a/ls/ls_ide_to_clang.go +++ b/ls/ls_ide_to_clang.go @@ -94,9 +94,8 @@ func (ls *INOLanguageServer) ide2ClangRange(logger jsonrpc.FunctionLogger, ideUR if ls.clangURIRefersToIno(clangURI) { if clangRange, ok := ls.sketchMapper.InoToCppLSPRangeOk(ideURI, ideRange); ok { return clangURI, clangRange, nil - } else { - return lsp.DocumentURI{}, lsp.Range{}, fmt.Errorf("invalid range %s:%s: could not be mapped to Arduino-preprocessed sketck.ino.cpp", ideURI, ideRange) } + return lsp.DocumentURI{}, lsp.Range{}, fmt.Errorf("invalid range %s:%s: could not be mapped to Arduino-preprocessed sketck.ino.cpp", ideURI, ideRange) } else if inSketch { // Convert other sketch file ranges (.cpp/.h) clangRange := ideRange diff --git a/ls/lsp_client_clangd.go b/ls/lsp_client_clangd.go index 60300af..d8ee176 100644 --- a/ls/lsp_client_clangd.go +++ b/ls/lsp_client_clangd.go @@ -21,6 +21,7 @@ type ClangdLSPClient struct { ls *INOLanguageServer } +// NewClangdLSPClient creates and returns a new client func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, ls *INOLanguageServer) *ClangdLSPClient { clangdConfFile := ls.buildPath.Join(".clangd") clangdConf := fmt.Sprintln("Diagnostics:") @@ -72,7 +73,7 @@ func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, l ls: ls, } client.conn = lsp.NewClient(clangdStdio, clangdStdio, client) - client.conn.SetLogger(&LSPLogger{ + client.conn.SetLogger(&Logger{ IncomingPrefix: "IDE LS <-- Clangd", OutgoingPrefix: "IDE LS --> Clangd", HiColor: color.HiRedString, @@ -82,10 +83,12 @@ func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, l return client } +// Run sends a Run notification to Clangd func (client *ClangdLSPClient) Run() { client.conn.Run() } +// Close sends an Exit notification to Clangd func (client *ClangdLSPClient) Close() { client.conn.Exit() // send "exit" notification to Clangd // TODO: kill client.conn @@ -93,62 +96,77 @@ func (client *ClangdLSPClient) Close() { // The following are events incoming from Clangd +// WindowShowMessageRequest is not implemented func (client *ClangdLSPClient) WindowShowMessageRequest(context.Context, jsonrpc.FunctionLogger, *lsp.ShowMessageRequestParams) (*lsp.MessageActionItem, *jsonrpc.ResponseError) { panic("unimplemented") } +// WindowShowDocument is not implemented func (client *ClangdLSPClient) WindowShowDocument(context.Context, jsonrpc.FunctionLogger, *lsp.ShowDocumentParams) (*lsp.ShowDocumentResult, *jsonrpc.ResponseError) { panic("unimplemented") } +// WindowWorkDoneProgressCreate is not implemented func (client *ClangdLSPClient) WindowWorkDoneProgressCreate(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { return client.ls.WindowWorkDoneProgressCreateReqFromClangd(ctx, logger, params) } +// ClientRegisterCapability is not implemented func (client *ClangdLSPClient) ClientRegisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.RegistrationParams) *jsonrpc.ResponseError { panic("unimplemented") } +// ClientUnregisterCapability is not implemented func (client *ClangdLSPClient) ClientUnregisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.UnregistrationParams) *jsonrpc.ResponseError { panic("unimplemented") } +// WorkspaceWorkspaceFolders is not implemented func (client *ClangdLSPClient) WorkspaceWorkspaceFolders(context.Context, jsonrpc.FunctionLogger) ([]lsp.WorkspaceFolder, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceConfiguration is not implemented func (client *ClangdLSPClient) WorkspaceConfiguration(context.Context, jsonrpc.FunctionLogger, *lsp.ConfigurationParams) ([]json.RawMessage, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceApplyEdit is not implemented func (client *ClangdLSPClient) WorkspaceApplyEdit(context.Context, jsonrpc.FunctionLogger, *lsp.ApplyWorkspaceEditParams) (*lsp.ApplyWorkspaceEditResult, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceCodeLensRefresh is not implemented func (client *ClangdLSPClient) WorkspaceCodeLensRefresh(context.Context, jsonrpc.FunctionLogger) *jsonrpc.ResponseError { panic("unimplemented") } +// Progress sends a Progress notification func (client *ClangdLSPClient) Progress(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { client.ls.ProgressNotifFromClangd(logger, progress) } +// LogTrace is not implemented func (client *ClangdLSPClient) LogTrace(jsonrpc.FunctionLogger, *lsp.LogTraceParams) { panic("unimplemented") } +// WindowShowMessage is not implemented func (client *ClangdLSPClient) WindowShowMessage(jsonrpc.FunctionLogger, *lsp.ShowMessageParams) { panic("unimplemented") } +// WindowLogMessage is not implemented func (client *ClangdLSPClient) WindowLogMessage(jsonrpc.FunctionLogger, *lsp.LogMessageParams) { panic("unimplemented") } +// TelemetryEvent is not implemented func (client *ClangdLSPClient) TelemetryEvent(jsonrpc.FunctionLogger, json.RawMessage) { panic("unimplemented") } +// TextDocumentPublishDiagnostics sends a notification to Publish Dignostics func (client *ClangdLSPClient) TextDocumentPublishDiagnostics(logger jsonrpc.FunctionLogger, params *lsp.PublishDiagnosticsParams) { go client.ls.PublishDiagnosticsNotifFromClangd(logger, params) } diff --git a/ls/lsp_logger.go b/ls/lsp_logger.go index 4f39eff..2488140 100644 --- a/ls/lsp_logger.go +++ b/ls/lsp_logger.go @@ -10,7 +10,8 @@ import ( "go.bug.st/lsp/jsonrpc" ) -type LSPLogger struct { +// Logger is a lsp logger +type Logger struct { IncomingPrefix, OutgoingPrefix string HiColor, LoColor func(format string, a ...interface{}) string ErrorColor func(format string, a ...interface{}) string @@ -20,69 +21,89 @@ func init() { log.SetFlags(log.Lmicroseconds) } -func (l *LSPLogger) LogOutgoingRequest(id string, method string, params json.RawMessage) { +// LogOutgoingRequest prints an outgoing request into the log +func (l *Logger) LogOutgoingRequest(id string, method string, params json.RawMessage) { log.Print(l.HiColor("%s REQU %s %s", l.OutgoingPrefix, method, id)) } -func (l *LSPLogger) LogOutgoingCancelRequest(id string) { + +// LogOutgoingCancelRequest prints an outgoing cancel request into the log +func (l *Logger) LogOutgoingCancelRequest(id string) { log.Print(l.LoColor("%s CANCEL %s", l.OutgoingPrefix, id)) } -func (l *LSPLogger) LogIncomingResponse(id string, method string, resp json.RawMessage, respErr *jsonrpc.ResponseError) { + +// LogIncomingResponse prints an incoming response into the log if there is no error +func (l *Logger) LogIncomingResponse(id string, method string, resp json.RawMessage, respErr *jsonrpc.ResponseError) { e := "" if respErr != nil { e = l.ErrorColor(" ERROR: %s", respErr.AsError()) } log.Print(l.LoColor("%s RESP %s %s%s", l.IncomingPrefix, method, id, e)) } -func (l *LSPLogger) LogOutgoingNotification(method string, params json.RawMessage) { + +// LogOutgoingNotification prints an outgoing notification into the log +func (l *Logger) LogOutgoingNotification(method string, params json.RawMessage) { log.Print(l.HiColor("%s NOTIF %s", l.OutgoingPrefix, method)) } -func (l *LSPLogger) LogIncomingRequest(id string, method string, params json.RawMessage) jsonrpc.FunctionLogger { +// LogIncomingRequest prints an incoming request into the log +func (l *Logger) LogIncomingRequest(id string, method string, params json.RawMessage) jsonrpc.FunctionLogger { spaces := " " log.Print(l.HiColor(fmt.Sprintf("%s REQU %s %s", l.IncomingPrefix, method, id))) - return &LSPFunctionLogger{ + return &FunctionLogger{ colorFunc: l.HiColor, prefix: fmt.Sprintf("%s %s %s", spaces[:len(l.IncomingPrefix)], method, id), } } -func (l *LSPLogger) LogIncomingCancelRequest(id string) { + +// LogIncomingCancelRequest prints an incoming cancel request into the log +func (l *Logger) LogIncomingCancelRequest(id string) { log.Print(l.LoColor("%s CANCEL %s", l.IncomingPrefix, id)) } -func (l *LSPLogger) LogOutgoingResponse(id string, method string, resp json.RawMessage, respErr *jsonrpc.ResponseError) { + +// LogOutgoingResponse prints an outgoing response into the log if there is no error +func (l *Logger) LogOutgoingResponse(id string, method string, resp json.RawMessage, respErr *jsonrpc.ResponseError) { e := "" if respErr != nil { e = l.ErrorColor(" ERROR: %s", respErr.AsError()) } log.Print(l.LoColor("%s RESP %s %s%s", l.OutgoingPrefix, method, id, e)) } -func (l *LSPLogger) LogIncomingNotification(method string, params json.RawMessage) jsonrpc.FunctionLogger { + +// LogIncomingNotification prints an incoming notification into the log +func (l *Logger) LogIncomingNotification(method string, params json.RawMessage) jsonrpc.FunctionLogger { spaces := " " log.Print(l.HiColor(fmt.Sprintf("%s NOTIF %s", l.IncomingPrefix, method))) - return &LSPFunctionLogger{ + return &FunctionLogger{ colorFunc: l.HiColor, prefix: fmt.Sprintf("%s %s", spaces[:len(l.IncomingPrefix)], method), } } -func (l *LSPLogger) LogIncomingDataDelay(delay time.Duration) { + +// LogIncomingDataDelay prints the delay of incoming data into the log +func (l *Logger) LogIncomingDataDelay(delay time.Duration) { log.Printf("IN Elapsed: %v", delay) } -func (l *LSPLogger) LogOutgoingDataDelay(delay time.Duration) { + +// LogOutgoingDataDelay prints the delay of outgoing data into the log +func (l *Logger) LogOutgoingDataDelay(delay time.Duration) { log.Printf("OUT Elapsed: %v", delay) } -type LSPFunctionLogger struct { +// FunctionLogger is a lsp function logger +type FunctionLogger struct { colorFunc func(format string, a ...interface{}) string prefix string } -func NewLSPFunctionLogger(colofFunction func(format string, a ...interface{}) string, prefix string) *LSPFunctionLogger { +// NewLSPFunctionLogger creates a new function logger +func NewLSPFunctionLogger(colofFunction func(format string, a ...interface{}) string, prefix string) *FunctionLogger { color.NoColor = false - return &LSPFunctionLogger{ + return &FunctionLogger{ colorFunc: colofFunction, prefix: prefix, } } -func (l *LSPFunctionLogger) Logf(format string, a ...interface{}) { +func (l *FunctionLogger) Logf(format string, a ...interface{}) { log.Print(l.colorFunc(l.prefix+": "+format, a...)) } diff --git a/ls/lsp_server_ide.go b/ls/lsp_server_ide.go index b1fd386..687977e 100644 --- a/ls/lsp_server_ide.go +++ b/ls/lsp_server_ide.go @@ -10,18 +10,20 @@ import ( "go.bug.st/lsp/jsonrpc" ) +// IDELSPServer is an IDE lsp server type IDELSPServer struct { conn *lsp.Server ls *INOLanguageServer } +// NewIDELSPServer creates and return a new server func NewIDELSPServer(logger jsonrpc.FunctionLogger, in io.Reader, out io.Writer, ls *INOLanguageServer) *IDELSPServer { server := &IDELSPServer{ ls: ls, } server.conn = lsp.NewServer(in, out, server) server.conn.RegisterCustomNotification("ino/didCompleteBuild", server.ArduinoBuildCompleted) - server.conn.SetLogger(&LSPLogger{ + server.conn.SetLogger(&Logger{ IncomingPrefix: "IDE --> LS", OutgoingPrefix: "IDE <-- LS", HiColor: color.HiGreenString, @@ -31,204 +33,254 @@ func NewIDELSPServer(logger jsonrpc.FunctionLogger, in io.Reader, out io.Writer, return server } +// Run runs the server connection func (server *IDELSPServer) Run() { server.conn.Run() } +// Initialize sends an initilize request func (server *IDELSPServer) Initialize(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) { return server.ls.InitializeReqFromIDE(ctx, logger, params) } +// Shutdown sends a shutdown request func (server *IDELSPServer) Shutdown(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { return server.ls.ShutdownReqFromIDE(ctx, logger) } +// WorkspaceSymbol is not implemented func (server *IDELSPServer) WorkspaceSymbol(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkspaceSymbolParams) ([]lsp.SymbolInformation, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceExecuteCommand is not implemented func (server *IDELSPServer) WorkspaceExecuteCommand(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.ExecuteCommandParams) (json.RawMessage, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceWillCreateFiles is not implemented func (server *IDELSPServer) WorkspaceWillCreateFiles(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CreateFilesParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceWillRenameFiles is not implemented func (server *IDELSPServer) WorkspaceWillRenameFiles(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.RenameFilesParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceWillDeleteFiles is not implemented func (server *IDELSPServer) WorkspaceWillDeleteFiles(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DeleteFilesParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentWillSaveWaitUntil is not implemented func (server *IDELSPServer) TextDocumentWillSaveWaitUntil(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WillSaveTextDocumentParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentCompletion is not implemented func (server *IDELSPServer) TextDocumentCompletion(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CompletionParams) (*lsp.CompletionList, *jsonrpc.ResponseError) { return server.ls.TextDocumentCompletionReqFromIDE(ctx, logger, params) } +// CompletionItemResolve is not implemented func (server *IDELSPServer) CompletionItemResolve(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CompletionItem) (*lsp.CompletionItem, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentHover sends a request to hover a text document func (server *IDELSPServer) TextDocumentHover(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.HoverParams) (*lsp.Hover, *jsonrpc.ResponseError) { return server.ls.TextDocumentHoverReqFromIDE(ctx, logger, params) } +// TextDocumentSignatureHelp requests help for text document signature func (server *IDELSPServer) TextDocumentSignatureHelp(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SignatureHelpParams) (*lsp.SignatureHelp, *jsonrpc.ResponseError) { return server.ls.TextDocumentSignatureHelpReqFromIDE(ctx, logger, params) } +// TextDocumentDeclaration is not implemented func (server *IDELSPServer) TextDocumentDeclaration(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DeclarationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentDefinition sends a request to define a text document func (server *IDELSPServer) TextDocumentDefinition(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { return server.ls.TextDocumentDefinitionReqFromIDE(ctx, logger, params) } +// TextDocumentTypeDefinition sends a request to define a type for the text document func (server *IDELSPServer) TextDocumentTypeDefinition(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.TypeDefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { return server.ls.TextDocumentTypeDefinitionReqFromIDE(ctx, logger, params) } +// TextDocumentImplementation sends a request to implement a text document func (server *IDELSPServer) TextDocumentImplementation(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.ImplementationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { return server.ls.TextDocumentImplementationReqFromIDE(ctx, logger, params) } +// TextDocumentReferences is not implemented func (server *IDELSPServer) TextDocumentReferences(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.ReferenceParams) ([]lsp.Location, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentDocumentHighlight sends a request to highlight a text document func (server *IDELSPServer) TextDocumentDocumentHighlight(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, *jsonrpc.ResponseError) { return server.ls.TextDocumentDocumentHighlightReqFromIDE(ctx, logger, params) } +// TextDocumentDocumentSymbol sends a request for text document symbol func (server *IDELSPServer) TextDocumentDocumentSymbol(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, []lsp.SymbolInformation, *jsonrpc.ResponseError) { return server.ls.TextDocumentDocumentSymbolReqFromIDE(ctx, logger, params) } +// TextDocumentCodeAction sends a request for text document code action func (server *IDELSPServer) TextDocumentCodeAction(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CodeActionParams) ([]lsp.CommandOrCodeAction, *jsonrpc.ResponseError) { return server.ls.TextDocumentCodeActionReqFromIDE(ctx, logger, params) } +// CodeActionResolve is not implemented func (server *IDELSPServer) CodeActionResolve(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CodeAction) (*lsp.CodeAction, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentCodeLens is not implemented func (server *IDELSPServer) TextDocumentCodeLens(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CodeLensParams) ([]lsp.CodeLens, *jsonrpc.ResponseError) { panic("unimplemented") } +// CodeLensResolve is not implemented func (server *IDELSPServer) CodeLensResolve(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CodeLens) (*lsp.CodeLens, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentDocumentLink is not implemented func (server *IDELSPServer) TextDocumentDocumentLink(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentLinkParams) ([]lsp.DocumentLink, *jsonrpc.ResponseError) { panic("unimplemented") } +// DocumentLinkResolve is not implemented func (server *IDELSPServer) DocumentLinkResolve(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentLink) (*lsp.DocumentLink, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentDocumentColor is not implemented func (server *IDELSPServer) TextDocumentDocumentColor(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentColorParams) ([]lsp.ColorInformation, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentColorPresentation is not implemented func (server *IDELSPServer) TextDocumentColorPresentation(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.ColorPresentationParams) ([]lsp.ColorPresentation, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentFormatting sends a request to format a text document func (server *IDELSPServer) TextDocumentFormatting(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { return server.ls.TextDocumentFormattingReqFromIDE(ctx, logger, params) } +// TextDocumentRangeFormatting sends a request to format the range a text document func (server *IDELSPServer) TextDocumentRangeFormatting(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { return server.ls.TextDocumentRangeFormattingReqFromIDE(ctx, logger, params) } +// TextDocumentOnTypeFormatting is not implemented func (server *IDELSPServer) TextDocumentOnTypeFormatting(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentOnTypeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentRename sends a request to rename a text document func (server *IDELSPServer) TextDocumentRename(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.RenameParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { return server.ls.TextDocumentRenameReqFromIDE(ctx, logger, params) } +// TextDocumentFoldingRange is not implemented func (server *IDELSPServer) TextDocumentFoldingRange(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.FoldingRangeParams) ([]lsp.FoldingRange, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentSelectionRange is not implemented func (server *IDELSPServer) TextDocumentSelectionRange(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SelectionRangeParams) ([]lsp.SelectionRange, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentPrepareCallHierarchy is not implemented func (server *IDELSPServer) TextDocumentPrepareCallHierarchy(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CallHierarchyPrepareParams) ([]lsp.CallHierarchyItem, *jsonrpc.ResponseError) { panic("unimplemented") } +// CallHierarchyIncomingCalls is not implemented func (server *IDELSPServer) CallHierarchyIncomingCalls(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CallHierarchyIncomingCallsParams) ([]lsp.CallHierarchyIncomingCall, *jsonrpc.ResponseError) { panic("unimplemented") } +// CallHierarchyOutgoingCalls is not implemented func (server *IDELSPServer) CallHierarchyOutgoingCalls(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CallHierarchyOutgoingCallsParams) ([]lsp.CallHierarchyOutgoingCall, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentSemanticTokensFull is not implemented func (server *IDELSPServer) TextDocumentSemanticTokensFull(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SemanticTokensParams) (*lsp.SemanticTokens, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentSemanticTokensFullDelta is not implemented func (server *IDELSPServer) TextDocumentSemanticTokensFullDelta(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SemanticTokensDeltaParams) (*lsp.SemanticTokens, *lsp.SemanticTokensDelta, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentSemanticTokensRange is not implemented func (server *IDELSPServer) TextDocumentSemanticTokensRange(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SemanticTokensRangeParams) (*lsp.SemanticTokens, *jsonrpc.ResponseError) { panic("unimplemented") } +// WorkspaceSemanticTokensRefresh is not implemented func (server *IDELSPServer) WorkspaceSemanticTokensRefresh(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { panic("unimplemented") } +// TextDocumentLinkedEditingRange is not implemented func (server *IDELSPServer) TextDocumentLinkedEditingRange(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.LinkedEditingRangeParams) (*lsp.LinkedEditingRanges, *jsonrpc.ResponseError) { panic("unimplemented") } +// TextDocumentMoniker is not implemented func (server *IDELSPServer) TextDocumentMoniker(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.MonikerParams) ([]lsp.Moniker, *jsonrpc.ResponseError) { panic("unimplemented") } // Notifications -> +// Progress is not implemented func (server *IDELSPServer) Progress(logger jsonrpc.FunctionLogger, params *lsp.ProgressParams) { panic("unimplemented") } +// Initialized sends an initialized notification func (server *IDELSPServer) Initialized(logger jsonrpc.FunctionLogger, params *lsp.InitializedParams) { server.ls.InitializedNotifFromIDE(logger, params) } +// Exit sends an exit notification func (server *IDELSPServer) Exit(logger jsonrpc.FunctionLogger) { server.ls.ExitNotifFromIDE(logger) } +// SetTrace sends a set trace notification func (server *IDELSPServer) SetTrace(logger jsonrpc.FunctionLogger, params *lsp.SetTraceParams) { server.ls.SetTraceNotifFromIDE(logger, params) } +// WindowWorkDoneProgressCancel is not implemented func (server *IDELSPServer) WindowWorkDoneProgressCancel(logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCancelParams) { panic("unimplemented") } +// WorkspaceDidChangeWorkspaceFolders is not implemented func (server *IDELSPServer) WorkspaceDidChangeWorkspaceFolders(logger jsonrpc.FunctionLogger, params *lsp.DidChangeWorkspaceFoldersParams) { panic("unimplemented") } +// WorkspaceDidChangeConfiguration purpose is explained below func (server *IDELSPServer) WorkspaceDidChangeConfiguration(logger jsonrpc.FunctionLogger, params *lsp.DidChangeConfigurationParams) { // At least one LSP client, Eglot, sends this by default when // first connecting, even if the otions are empty. @@ -240,45 +292,54 @@ func (server *IDELSPServer) WorkspaceDidChangeConfiguration(logger jsonrpc.Funct } +// WorkspaceDidChangeWatchedFiles is not implemented func (server *IDELSPServer) WorkspaceDidChangeWatchedFiles(logger jsonrpc.FunctionLogger, params *lsp.DidChangeWatchedFilesParams) { panic("unimplemented") } +// WorkspaceDidCreateFiles is not implemented func (server *IDELSPServer) WorkspaceDidCreateFiles(logger jsonrpc.FunctionLogger, params *lsp.CreateFilesParams) { panic("unimplemented") } +// WorkspaceDidRenameFiles is not implemented func (server *IDELSPServer) WorkspaceDidRenameFiles(logger jsonrpc.FunctionLogger, params *lsp.RenameFilesParams) { panic("unimplemented") } +// WorkspaceDidDeleteFiles is not implemented func (server *IDELSPServer) WorkspaceDidDeleteFiles(logger jsonrpc.FunctionLogger, params *lsp.DeleteFilesParams) { panic("unimplemented") } +// TextDocumentDidOpen sends a notification the a text document is open func (server *IDELSPServer) TextDocumentDidOpen(logger jsonrpc.FunctionLogger, params *lsp.DidOpenTextDocumentParams) { server.ls.TextDocumentDidOpenNotifFromIDE(logger, params) } +// TextDocumentDidChange sends a notification the a text document has changed func (server *IDELSPServer) TextDocumentDidChange(logger jsonrpc.FunctionLogger, params *lsp.DidChangeTextDocumentParams) { server.ls.TextDocumentDidChangeNotifFromIDE(logger, params) } +// TextDocumentWillSave is not implemented func (server *IDELSPServer) TextDocumentWillSave(logger jsonrpc.FunctionLogger, params *lsp.WillSaveTextDocumentParams) { panic("unimplemented") } +// TextDocumentDidSave sends a notification the a text document has been saved func (server *IDELSPServer) TextDocumentDidSave(logger jsonrpc.FunctionLogger, params *lsp.DidSaveTextDocumentParams) { server.ls.TextDocumentDidSaveNotifFromIDE(logger, params) } +// TextDocumentDidClose sends a notification the a text document has been closed func (server *IDELSPServer) TextDocumentDidClose(logger jsonrpc.FunctionLogger, params *lsp.DidCloseTextDocumentParams) { server.ls.TextDocumentDidCloseNotifFromIDE(logger, params) } // DidCompleteBuildParams is a custom notification from the Arduino IDE, sent type DidCompleteBuildParams struct { - BuildOutputUri *lsp.DocumentURI `json:"buildOutputUri"` + BuildOutputURI *lsp.DocumentURI `json:"buildOutputUri"` } func (server *IDELSPServer) ArduinoBuildCompleted(logger jsonrpc.FunctionLogger, raw json.RawMessage) { diff --git a/ls/progress.go b/ls/progress.go index 8f00f0d..4ba36ed 100644 --- a/ls/progress.go +++ b/ls/progress.go @@ -34,6 +34,7 @@ type progressProxy struct { endReq *lsp.WorkDoneProgressEnd } +// NewProgressProxy creates a new ProgressProxyHandler and returns its pointer func NewProgressProxy(conn *lsp.Server) *ProgressProxyHandler { res := &ProgressProxyHandler{ conn: conn, From edeb72716525652fc9d08529f026d92d55770011 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:21:39 +0200 Subject: [PATCH 3/8] Made sketchRebuilder private --- ls/builder.go | 14 +++++++------- ls/ls.go | 4 ++-- sourcemapper/ino.go | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ls/builder.go b/ls/builder.go index c716e03..f4338bd 100644 --- a/ls/builder.go +++ b/ls/builder.go @@ -25,16 +25,16 @@ import ( "google.golang.org/grpc" ) -type SketchRebuilder struct { +type sketchRebuilder struct { ls *INOLanguageServer trigger chan chan<- bool cancel func() mutex sync.Mutex } -// NewSketchBuilder makes a new SketchRebuilder and returns its pointer -func NewSketchBuilder(ls *INOLanguageServer) *SketchRebuilder { - res := &SketchRebuilder{ +// newSketchBuilder makes a new SketchRebuilder and returns its pointer +func newSketchBuilder(ls *INOLanguageServer) *sketchRebuilder { + res := &sketchRebuilder{ trigger: make(chan chan<- bool, 1), cancel: func() {}, ls: ls, @@ -59,7 +59,7 @@ func (ls *INOLanguageServer) triggerRebuild() { } // TriggerRebuild schedule a sketch rebuild (it will be executed asynchronously) -func (r *SketchRebuilder) TriggerRebuild(completed chan<- bool) { +func (r *sketchRebuilder) TriggerRebuild(completed chan<- bool) { r.mutex.Lock() defer r.mutex.Unlock() @@ -70,7 +70,7 @@ func (r *SketchRebuilder) TriggerRebuild(completed chan<- bool) { } } -func (r *SketchRebuilder) rebuilderLoop() { +func (r *sketchRebuilder) rebuilderLoop() { logger := NewLSPFunctionLogger(color.HiMagentaString, "SKETCH REBUILD: ") for { completed := <-r.trigger @@ -106,7 +106,7 @@ func (r *SketchRebuilder) rebuilderLoop() { } } -func (r *SketchRebuilder) doRebuildArduinoPreprocessedSketch(ctx context.Context, logger jsonrpc.FunctionLogger) error { +func (r *sketchRebuilder) doRebuildArduinoPreprocessedSketch(ctx context.Context, logger jsonrpc.FunctionLogger) error { ls := r.ls if success, err := ls.generateBuildEnvironment(ctx, !r.ls.config.SkipLibrariesDiscoveryOnRebuild, logger); err != nil { return err diff --git a/ls/ls.go b/ls/ls.go index 151b5f9..eafd6ff 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -46,7 +46,7 @@ type INOLanguageServer struct { sketchTrackedFilesCount int trackedIdeDocs map[string]lsp.TextDocumentItem ideInoDocsWithDiagnostics map[lsp.DocumentURI]bool - sketchRebuilder *SketchRebuilder + sketchRebuilder *sketchRebuilder } // Config describes the language server configuration. @@ -123,7 +123,7 @@ func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, config *Config) *IN config: config, } ls.clangdStarted = sync.NewCond(&ls.dataMux) - ls.sketchRebuilder = NewSketchBuilder(ls) + ls.sketchRebuilder = newSketchBuilder(ls) if tmp, err := paths.MkTempDir("", "arduino-language-server"); err != nil { log.Fatalf("Could not create temp folder: %s", err) diff --git a/sourcemapper/ino.go b/sourcemapper/ino.go index 6911efd..1c5648a 100644 --- a/sourcemapper/ino.go +++ b/sourcemapper/ino.go @@ -30,6 +30,7 @@ var NotIno = InoLine{"/not-ino", 0} // NotInoURI is the DocumentURI that do not belongs to an .ino file var NotInoURI, _ = lsp.NewDocumentURIFromURL("file:///not-ino") +// SourceRevision is a source code tagged with a version number type SourceRevision struct { Version int Text string From d17645afe811c93fd6a425ab009e3bfb7f38447a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:26:20 +0200 Subject: [PATCH 4/8] Added comment and renamed UnknownURI->UnknownURIError --- ls/ls.go | 7 ++++--- ls/ls_clang_to_ide.go | 2 +- ls/ls_ide_to_clang.go | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ls/ls.go b/ls/ls.go index eafd6ff..76a0d9b 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -1064,7 +1064,7 @@ func (ls *INOLanguageServer) TextDocumentDidChangeNotifFromIDE(logger jsonrpc.Fu // Apply the change to the tracked sketch file. trackedIdeDocID := ideTextDocIdentifier.URI.AsPath().String() if doc, ok := ls.trackedIdeDocs[trackedIdeDocID]; !ok { - logger.Logf("Error: %s", &UnknownURI{ideTextDocIdentifier.URI}) + logger.Logf("Error: %s", &UnknownURIError{ideTextDocIdentifier.URI}) return } else if updatedDoc, err := textedits.ApplyLSPTextDocumentContentChangeEvent(doc, ideParams); err != nil { logger.Logf("Error: %s", err) @@ -1598,10 +1598,11 @@ func (ls *INOLanguageServer) cpp2inoTextEdit(logger jsonrpc.FunctionLogger, cppU return inoURI, inoEdit, inPreprocessed, err } -type UnknownURI struct { +// UnknownURIError is an error when an URI is not recognized +type UnknownURIError struct { URI lsp.DocumentURI } -func (e *UnknownURI) Error() string { +func (e *UnknownURIError) Error() string { return "Document is not available: " + e.URI.String() } diff --git a/ls/ls_clang_to_ide.go b/ls/ls_clang_to_ide.go index 76e1298..95ce82c 100644 --- a/ls/ls_clang_to_ide.go +++ b/ls/ls_clang_to_ide.go @@ -87,7 +87,7 @@ func (ls *INOLanguageServer) clang2IdeDocumentURI(logger jsonrpc.FunctionLogger, return ideDoc.URI, nil } } - return lsp.DocumentURI{}, &UnknownURI{URI: clangURI} + return lsp.DocumentURI{}, &UnknownURIError{URI: clangURI} } // /another/global/path/to/source.cpp <-> /another/global/path/to/source.cpp diff --git a/ls/ls_ide_to_clang.go b/ls/ls_ide_to_clang.go index 62d6842..fb3e9e4 100644 --- a/ls/ls_ide_to_clang.go +++ b/ls/ls_ide_to_clang.go @@ -20,7 +20,7 @@ func (ls *INOLanguageServer) idePathToIdeURI(logger jsonrpc.FunctionLogger, inoP logger.Logf(" !!! > %s", p) } uri := lsp.NewDocumentURI(inoPath) - return uri, &UnknownURI{uri} + return uri, &UnknownURIError{uri} } return doc.URI, nil } @@ -44,7 +44,7 @@ func (ls *INOLanguageServer) ide2ClangDocumentURI(logger jsonrpc.FunctionLogger, inside, err := idePath.IsInsideDir(ls.sketchRoot) if err != nil { logger.Logf("ERROR: could not determine if '%s' is inside '%s'", idePath, ls.sketchRoot) - return lsp.NilURI, false, &UnknownURI{ideURI} + return lsp.NilURI, false, &UnknownURIError{ideURI} } if !inside { clangURI := ideURI From c81f0908e9af0521f272b0e46b8d40817e326a67 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:28:33 +0200 Subject: [PATCH 5/8] Made ClangdLSPClient private --- ls/ls.go | 4 ++-- ls/lsp_client_clangd.go | 42 ++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ls/ls.go b/ls/ls.go index 76a0d9b..f2c35ee 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -30,7 +30,7 @@ import ( type INOLanguageServer struct { config *Config IDE *IDELSPServer - Clangd *ClangdLSPClient + Clangd *clangdLSPClient progressHandler *ProgressProxyHandler closing chan bool @@ -196,7 +196,7 @@ func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger js } // Start clangd - ls.Clangd = NewClangdLSPClient(logger, dataFolder, ls) + ls.Clangd = newClangdLSPClient(logger, dataFolder, ls) go func() { defer streams.CatchAndLogPanic() ls.Clangd.Run() diff --git a/ls/lsp_client_clangd.go b/ls/lsp_client_clangd.go index d8ee176..c8db132 100644 --- a/ls/lsp_client_clangd.go +++ b/ls/lsp_client_clangd.go @@ -16,13 +16,13 @@ import ( "go.bug.st/lsp/jsonrpc" ) -type ClangdLSPClient struct { +type clangdLSPClient struct { conn *lsp.Client ls *INOLanguageServer } -// NewClangdLSPClient creates and returns a new client -func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, ls *INOLanguageServer) *ClangdLSPClient { +// newClangdLSPClient creates and returns a new client +func newClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, ls *INOLanguageServer) *clangdLSPClient { clangdConfFile := ls.buildPath.Join(".clangd") clangdConf := fmt.Sprintln("Diagnostics:") clangdConf += fmt.Sprintln(" Suppress: [anon_bitfield_qualifiers]") @@ -69,7 +69,7 @@ func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, l go io.Copy(os.Stderr, clangdStderr) } - client := &ClangdLSPClient{ + client := &clangdLSPClient{ ls: ls, } client.conn = lsp.NewClient(clangdStdio, clangdStdio, client) @@ -84,12 +84,12 @@ func NewClangdLSPClient(logger jsonrpc.FunctionLogger, dataFolder *paths.Path, l } // Run sends a Run notification to Clangd -func (client *ClangdLSPClient) Run() { +func (client *clangdLSPClient) Run() { client.conn.Run() } // Close sends an Exit notification to Clangd -func (client *ClangdLSPClient) Close() { +func (client *clangdLSPClient) Close() { client.conn.Exit() // send "exit" notification to Clangd // TODO: kill client.conn } @@ -97,76 +97,76 @@ func (client *ClangdLSPClient) Close() { // The following are events incoming from Clangd // WindowShowMessageRequest is not implemented -func (client *ClangdLSPClient) WindowShowMessageRequest(context.Context, jsonrpc.FunctionLogger, *lsp.ShowMessageRequestParams) (*lsp.MessageActionItem, *jsonrpc.ResponseError) { +func (client *clangdLSPClient) WindowShowMessageRequest(context.Context, jsonrpc.FunctionLogger, *lsp.ShowMessageRequestParams) (*lsp.MessageActionItem, *jsonrpc.ResponseError) { panic("unimplemented") } // WindowShowDocument is not implemented -func (client *ClangdLSPClient) WindowShowDocument(context.Context, jsonrpc.FunctionLogger, *lsp.ShowDocumentParams) (*lsp.ShowDocumentResult, *jsonrpc.ResponseError) { +func (client *clangdLSPClient) WindowShowDocument(context.Context, jsonrpc.FunctionLogger, *lsp.ShowDocumentParams) (*lsp.ShowDocumentResult, *jsonrpc.ResponseError) { panic("unimplemented") } // WindowWorkDoneProgressCreate is not implemented -func (client *ClangdLSPClient) WindowWorkDoneProgressCreate(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { +func (client *clangdLSPClient) WindowWorkDoneProgressCreate(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { return client.ls.WindowWorkDoneProgressCreateReqFromClangd(ctx, logger, params) } // ClientRegisterCapability is not implemented -func (client *ClangdLSPClient) ClientRegisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.RegistrationParams) *jsonrpc.ResponseError { +func (client *clangdLSPClient) ClientRegisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.RegistrationParams) *jsonrpc.ResponseError { panic("unimplemented") } // ClientUnregisterCapability is not implemented -func (client *ClangdLSPClient) ClientUnregisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.UnregistrationParams) *jsonrpc.ResponseError { +func (client *clangdLSPClient) ClientUnregisterCapability(context.Context, jsonrpc.FunctionLogger, *lsp.UnregistrationParams) *jsonrpc.ResponseError { panic("unimplemented") } // WorkspaceWorkspaceFolders is not implemented -func (client *ClangdLSPClient) WorkspaceWorkspaceFolders(context.Context, jsonrpc.FunctionLogger) ([]lsp.WorkspaceFolder, *jsonrpc.ResponseError) { +func (client *clangdLSPClient) WorkspaceWorkspaceFolders(context.Context, jsonrpc.FunctionLogger) ([]lsp.WorkspaceFolder, *jsonrpc.ResponseError) { panic("unimplemented") } // WorkspaceConfiguration is not implemented -func (client *ClangdLSPClient) WorkspaceConfiguration(context.Context, jsonrpc.FunctionLogger, *lsp.ConfigurationParams) ([]json.RawMessage, *jsonrpc.ResponseError) { +func (client *clangdLSPClient) WorkspaceConfiguration(context.Context, jsonrpc.FunctionLogger, *lsp.ConfigurationParams) ([]json.RawMessage, *jsonrpc.ResponseError) { panic("unimplemented") } // WorkspaceApplyEdit is not implemented -func (client *ClangdLSPClient) WorkspaceApplyEdit(context.Context, jsonrpc.FunctionLogger, *lsp.ApplyWorkspaceEditParams) (*lsp.ApplyWorkspaceEditResult, *jsonrpc.ResponseError) { +func (client *clangdLSPClient) WorkspaceApplyEdit(context.Context, jsonrpc.FunctionLogger, *lsp.ApplyWorkspaceEditParams) (*lsp.ApplyWorkspaceEditResult, *jsonrpc.ResponseError) { panic("unimplemented") } // WorkspaceCodeLensRefresh is not implemented -func (client *ClangdLSPClient) WorkspaceCodeLensRefresh(context.Context, jsonrpc.FunctionLogger) *jsonrpc.ResponseError { +func (client *clangdLSPClient) WorkspaceCodeLensRefresh(context.Context, jsonrpc.FunctionLogger) *jsonrpc.ResponseError { panic("unimplemented") } // Progress sends a Progress notification -func (client *ClangdLSPClient) Progress(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { +func (client *clangdLSPClient) Progress(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { client.ls.ProgressNotifFromClangd(logger, progress) } // LogTrace is not implemented -func (client *ClangdLSPClient) LogTrace(jsonrpc.FunctionLogger, *lsp.LogTraceParams) { +func (client *clangdLSPClient) LogTrace(jsonrpc.FunctionLogger, *lsp.LogTraceParams) { panic("unimplemented") } // WindowShowMessage is not implemented -func (client *ClangdLSPClient) WindowShowMessage(jsonrpc.FunctionLogger, *lsp.ShowMessageParams) { +func (client *clangdLSPClient) WindowShowMessage(jsonrpc.FunctionLogger, *lsp.ShowMessageParams) { panic("unimplemented") } // WindowLogMessage is not implemented -func (client *ClangdLSPClient) WindowLogMessage(jsonrpc.FunctionLogger, *lsp.LogMessageParams) { +func (client *clangdLSPClient) WindowLogMessage(jsonrpc.FunctionLogger, *lsp.LogMessageParams) { panic("unimplemented") } // TelemetryEvent is not implemented -func (client *ClangdLSPClient) TelemetryEvent(jsonrpc.FunctionLogger, json.RawMessage) { +func (client *clangdLSPClient) TelemetryEvent(jsonrpc.FunctionLogger, json.RawMessage) { panic("unimplemented") } // TextDocumentPublishDiagnostics sends a notification to Publish Dignostics -func (client *ClangdLSPClient) TextDocumentPublishDiagnostics(logger jsonrpc.FunctionLogger, params *lsp.PublishDiagnosticsParams) { +func (client *clangdLSPClient) TextDocumentPublishDiagnostics(logger jsonrpc.FunctionLogger, params *lsp.PublishDiagnosticsParams) { go client.ls.PublishDiagnosticsNotifFromClangd(logger, params) } From 7b559967017a2b8524ecd869e3f8d395fccdac71 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:25:33 +0200 Subject: [PATCH 6/8] Added some godoc comments --- ls/ls.go | 2 ++ ls/lsp_logger.go | 1 + ls/lsp_server_ide.go | 1 + 3 files changed, 4 insertions(+) diff --git a/ls/ls.go b/ls/ls.go index f2c35ee..d678dde 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -1340,6 +1340,7 @@ func (ls *INOLanguageServer) ideURIIsPartOfTheSketch(ideURI lsp.DocumentURI) boo return res } +// ProgressNotifFromClangd handles a progress request from clangd func (ls *INOLanguageServer) ProgressNotifFromClangd(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { var token string if err := json.Unmarshal(progress.Token, &token); err != nil { @@ -1361,6 +1362,7 @@ func (ls *INOLanguageServer) ProgressNotifFromClangd(logger jsonrpc.FunctionLogg } } +// WindowWorkDoneProgressCreateReqFromClangd handles a progress create request from clangd func (ls *INOLanguageServer) WindowWorkDoneProgressCreateReqFromClangd(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { var token string if err := json.Unmarshal(params.Token, &token); err != nil { diff --git a/ls/lsp_logger.go b/ls/lsp_logger.go index 2488140..f56c3ed 100644 --- a/ls/lsp_logger.go +++ b/ls/lsp_logger.go @@ -104,6 +104,7 @@ func NewLSPFunctionLogger(colofFunction func(format string, a ...interface{}) st } } +// Logf logs the given message func (l *FunctionLogger) Logf(format string, a ...interface{}) { log.Print(l.colorFunc(l.prefix+": "+format, a...)) } diff --git a/ls/lsp_server_ide.go b/ls/lsp_server_ide.go index 687977e..b9960d2 100644 --- a/ls/lsp_server_ide.go +++ b/ls/lsp_server_ide.go @@ -342,6 +342,7 @@ type DidCompleteBuildParams struct { BuildOutputURI *lsp.DocumentURI `json:"buildOutputUri"` } +// ArduinoBuildCompleted handles "buildComplete" messages from the IDE func (server *IDELSPServer) ArduinoBuildCompleted(logger jsonrpc.FunctionLogger, raw json.RawMessage) { if !server.ls.config.SkipLibrariesDiscoveryOnRebuild { return From b0b2d2c85347f5bf55548fe7672ba9b925efb9df Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:30:57 +0200 Subject: [PATCH 7/8] Made ProgressProxyHandler private --- ls/ls.go | 4 ++-- ls/progress.go | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ls/ls.go b/ls/ls.go index d678dde..1c2c715 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -32,7 +32,7 @@ type INOLanguageServer struct { IDE *IDELSPServer Clangd *clangdLSPClient - progressHandler *ProgressProxyHandler + progressHandler *progressProxyHandler closing chan bool clangdStarted *sync.Cond dataMux sync.RWMutex @@ -144,7 +144,7 @@ func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, config *Config) *IN logger.Logf("Language server FULL build path: %s", ls.fullBuildPath) ls.IDE = NewIDELSPServer(logger, stdin, stdout, ls) - ls.progressHandler = NewProgressProxy(ls.IDE.conn) + ls.progressHandler = newProgressProxy(ls.IDE.conn) go func() { defer streams.CatchAndLogPanic() ls.IDE.Run() diff --git a/ls/progress.go b/ls/progress.go index 4ba36ed..76de479 100644 --- a/ls/progress.go +++ b/ls/progress.go @@ -9,7 +9,7 @@ import ( "go.bug.st/lsp" ) -type ProgressProxyHandler struct { +type progressProxyHandler struct { conn *lsp.Server mux sync.Mutex actionRequiredCond *sync.Cond @@ -34,9 +34,9 @@ type progressProxy struct { endReq *lsp.WorkDoneProgressEnd } -// NewProgressProxy creates a new ProgressProxyHandler and returns its pointer -func NewProgressProxy(conn *lsp.Server) *ProgressProxyHandler { - res := &ProgressProxyHandler{ +// newProgressProxy creates a new ProgressProxyHandler and returns its pointer +func newProgressProxy(conn *lsp.Server) *progressProxyHandler { + res := &progressProxyHandler{ conn: conn, proxies: map[string]*progressProxy{}, } @@ -48,7 +48,7 @@ func NewProgressProxy(conn *lsp.Server) *ProgressProxyHandler { return res } -func (p *ProgressProxyHandler) handlerLoop() { +func (p *progressProxyHandler) handlerLoop() { p.mux.Lock() defer p.mux.Unlock() @@ -70,7 +70,7 @@ func (p *ProgressProxyHandler) handlerLoop() { } } -func (p *ProgressProxyHandler) handleProxy(id string, proxy *progressProxy) { +func (p *progressProxyHandler) handleProxy(id string, proxy *progressProxy) { switch proxy.currentStatus { case progressProxyNew: p.mux.Unlock() @@ -132,7 +132,7 @@ func (p *ProgressProxyHandler) handleProxy(id string, proxy *progressProxy) { } } -func (p *ProgressProxyHandler) Create(id string) { +func (p *progressProxyHandler) Create(id string) { p.mux.Lock() defer p.mux.Unlock() @@ -148,7 +148,7 @@ func (p *ProgressProxyHandler) Create(id string) { p.actionRequiredCond.Broadcast() } -func (p *ProgressProxyHandler) Begin(id string, req *lsp.WorkDoneProgressBegin) { +func (p *progressProxyHandler) Begin(id string, req *lsp.WorkDoneProgressBegin) { p.mux.Lock() defer p.mux.Unlock() @@ -168,7 +168,7 @@ func (p *ProgressProxyHandler) Begin(id string, req *lsp.WorkDoneProgressBegin) p.actionRequiredCond.Broadcast() } -func (p *ProgressProxyHandler) Report(id string, req *lsp.WorkDoneProgressReport) { +func (p *progressProxyHandler) Report(id string, req *lsp.WorkDoneProgressReport) { p.mux.Lock() defer p.mux.Unlock() @@ -184,7 +184,7 @@ func (p *ProgressProxyHandler) Report(id string, req *lsp.WorkDoneProgressReport p.actionRequiredCond.Broadcast() } -func (p *ProgressProxyHandler) End(id string, req *lsp.WorkDoneProgressEnd) { +func (p *progressProxyHandler) End(id string, req *lsp.WorkDoneProgressEnd) { p.mux.Lock() defer p.mux.Unlock() @@ -198,7 +198,7 @@ func (p *ProgressProxyHandler) End(id string, req *lsp.WorkDoneProgressEnd) { p.actionRequiredCond.Broadcast() } -func (p *ProgressProxyHandler) Shutdown() { +func (p *progressProxyHandler) Shutdown() { p.mux.Lock() defer p.mux.Unlock() From 39e09a4264cb04981bd6ff124bdfca879a0c74ee Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 4 Aug 2022 10:53:49 +0200 Subject: [PATCH 8/8] Made all message callback private --- ls/ls.go | 75 ++++++++++++++--------------------------- ls/lsp_client_clangd.go | 6 ++-- ls/lsp_server_ide.go | 44 ++++++++++++------------ 3 files changed, 50 insertions(+), 75 deletions(-) diff --git a/ls/ls.go b/ls/ls.go index 1c2c715..0ad3c1a 100644 --- a/ls/ls.go +++ b/ls/ls.go @@ -155,8 +155,7 @@ func NewINOLanguageServer(stdin io.Reader, stdout io.Writer, config *Config) *IN return ls } -// InitializeReqFromIDE initializes a new request from the IDE -func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) initializeReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) { ls.writeLock(logger, false) ls.sketchRoot = ideParams.RootURI.AsPath() ls.sketchName = ls.sketchRoot.Base() @@ -364,8 +363,7 @@ func (ls *INOLanguageServer) InitializeReqFromIDE(ctx context.Context, logger js return resp, nil } -// ShutdownReqFromIDE executes a shutdown request from the IDE -func (ls *INOLanguageServer) ShutdownReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { +func (ls *INOLanguageServer) shutdownReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { done := make(chan bool) go func() { ls.progressHandler.Shutdown() @@ -376,8 +374,7 @@ func (ls *INOLanguageServer) ShutdownReqFromIDE(ctx context.Context, logger json return nil } -// TextDocumentCompletionReqFromIDE handles a text document completion request received from the IDE -func (ls *INOLanguageServer) TextDocumentCompletionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CompletionParams) (*lsp.CompletionList, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentCompletionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CompletionParams) (*lsp.CompletionList, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -471,8 +468,7 @@ func (ls *INOLanguageServer) TextDocumentCompletionReqFromIDE(ctx context.Contex return ideCompletionList, nil } -// TextDocumentHoverReqFromIDE handles a text document hover request received from the IDE -func (ls *INOLanguageServer) TextDocumentHoverReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.HoverParams) (*lsp.Hover, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentHoverReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.HoverParams) (*lsp.Hover, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -523,8 +519,7 @@ func (ls *INOLanguageServer) TextDocumentHoverReqFromIDE(ctx context.Context, lo return &ideResp, nil } -// TextDocumentSignatureHelpReqFromIDE handles a text document signature help request received from the IDE -func (ls *INOLanguageServer) TextDocumentSignatureHelpReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.SignatureHelpParams) (*lsp.SignatureHelp, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentSignatureHelpReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.SignatureHelpParams) (*lsp.SignatureHelp, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -555,8 +550,7 @@ func (ls *INOLanguageServer) TextDocumentSignatureHelpReqFromIDE(ctx context.Con return ideSignatureHelp, nil } -// TextDocumentDefinitionReqFromIDE handles a text document definition request received from the IDE -func (ls *INOLanguageServer) TextDocumentDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -600,8 +594,7 @@ func (ls *INOLanguageServer) TextDocumentDefinitionReqFromIDE(ctx context.Contex return ideLocations, ideLocationLinks, nil } -// TextDocumentTypeDefinitionReqFromIDE handles a text document type definition request received from the IDE -func (ls *INOLanguageServer) TextDocumentTypeDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.TypeDefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentTypeDefinitionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.TypeDefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { // XXX: This capability is not advertised in the initialization message (clangd // does not advertise it either, so maybe we should just not implement it) ls.readLock(logger, true) @@ -647,8 +640,7 @@ func (ls *INOLanguageServer) TextDocumentTypeDefinitionReqFromIDE(ctx context.Co return ideLocations, ideLocationLinks, nil } -// TextDocumentImplementationReqFromIDE handles a text document implementation request received from the IDE -func (ls *INOLanguageServer) TextDocumentImplementationReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.ImplementationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentImplementationReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.ImplementationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -692,8 +684,7 @@ func (ls *INOLanguageServer) TextDocumentImplementationReqFromIDE(ctx context.Co return ideLocations, inoLocationLinks, nil } -// TextDocumentDocumentHighlightReqFromIDE handles a text document highlight request received from the IDE -func (ls *INOLanguageServer) TextDocumentDocumentHighlightReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentDocumentHighlightReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -740,8 +731,7 @@ func (ls *INOLanguageServer) TextDocumentDocumentHighlightReqFromIDE(ctx context return ideHighlights, nil } -// TextDocumentDocumentSymbolReqFromIDE handles a text document symbol request received from the IDE -func (ls *INOLanguageServer) TextDocumentDocumentSymbolReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, []lsp.SymbolInformation, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentDocumentSymbolReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, []lsp.SymbolInformation, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -787,8 +777,7 @@ func (ls *INOLanguageServer) TextDocumentDocumentSymbolReqFromIDE(ctx context.Co return ideDocSymbols, ideSymbolsInformation, nil } -// TextDocumentCodeActionReqFromIDE handles a text document code action request received from the IDE -func (ls *INOLanguageServer) TextDocumentCodeActionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CodeActionParams) ([]lsp.CommandOrCodeAction, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentCodeActionReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.CodeActionParams) ([]lsp.CommandOrCodeAction, *jsonrpc.ResponseError) { ls.readLock(logger, true) defer ls.readUnlock(logger) @@ -857,8 +846,7 @@ func (ls *INOLanguageServer) TextDocumentCodeActionReqFromIDE(ctx context.Contex return ideCommandsOrCodeActions, nil } -// TextDocumentFormattingReqFromIDE handles a text document formatting request received from the IDE -func (ls *INOLanguageServer) TextDocumentFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -913,8 +901,7 @@ func (ls *INOLanguageServer) TextDocumentFormattingReqFromIDE(ctx context.Contex return inoEdits, nil } -// TextDocumentRangeFormattingReqFromIDE handles a text document range formatting request received from the IDE -func (ls *INOLanguageServer) TextDocumentRangeFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentRangeFormattingReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -967,20 +954,17 @@ func (ls *INOLanguageServer) TextDocumentRangeFormattingReqFromIDE(ctx context.C return inoEdits, nil } -// InitializedNotifFromIDE initializes a notification from the IDE -func (ls *INOLanguageServer) InitializedNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.InitializedParams) { +func (ls *INOLanguageServer) initializedNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.InitializedParams) { logger.Logf("Notification is not propagated to clangd") } -// ExitNotifFromIDE logs an exit notification from the IDE -func (ls *INOLanguageServer) ExitNotifFromIDE(logger jsonrpc.FunctionLogger) { +func (ls *INOLanguageServer) exitNotifFromIDE(logger jsonrpc.FunctionLogger) { ls.Clangd.conn.Exit() logger.Logf("Arduino Language Server is shutting down.") os.Exit(0) } -// TextDocumentDidOpenNotifFromIDE handles a notification from the IDE that TextDocument is open -func (ls *INOLanguageServer) TextDocumentDidOpenNotifFromIDE(logger jsonrpc.FunctionLogger, ideParam *lsp.DidOpenTextDocumentParams) { +func (ls *INOLanguageServer) textDocumentDidOpenNotifFromIDE(logger jsonrpc.FunctionLogger, ideParam *lsp.DidOpenTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1039,8 +1023,7 @@ func (ls *INOLanguageServer) TextDocumentDidOpenNotifFromIDE(logger jsonrpc.Func } } -// TextDocumentDidChangeNotifFromIDE handles a notification from the IDE that TextDocument changed -func (ls *INOLanguageServer) TextDocumentDidChangeNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidChangeTextDocumentParams) { +func (ls *INOLanguageServer) textDocumentDidChangeNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidChangeTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1136,8 +1119,7 @@ func (ls *INOLanguageServer) TextDocumentDidChangeNotifFromIDE(logger jsonrpc.Fu } } -// TextDocumentDidSaveNotifFromIDE handles a notification from the IDE that TextDocument has been saved -func (ls *INOLanguageServer) TextDocumentDidSaveNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidSaveTextDocumentParams) { +func (ls *INOLanguageServer) textDocumentDidSaveNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidSaveTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1148,8 +1130,7 @@ func (ls *INOLanguageServer) TextDocumentDidSaveNotifFromIDE(logger jsonrpc.Func ls.triggerRebuild() } -// TextDocumentDidCloseNotifFromIDE handles a notification from the IDE that TextDocument has been closed -func (ls *INOLanguageServer) TextDocumentDidCloseNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidCloseTextDocumentParams) { +func (ls *INOLanguageServer) textDocumentDidCloseNotifFromIDE(logger jsonrpc.FunctionLogger, ideParams *lsp.DidCloseTextDocumentParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1192,8 +1173,7 @@ func (ls *INOLanguageServer) TextDocumentDidCloseNotifFromIDE(logger jsonrpc.Fun } } -// FullBuildCompletedFromIDE receives a full build from the IDE and copies the results -func (ls *INOLanguageServer) FullBuildCompletedFromIDE(logger jsonrpc.FunctionLogger, params *DidCompleteBuildParams) { +func (ls *INOLanguageServer) fullBuildCompletedFromIDE(logger jsonrpc.FunctionLogger, params *DidCompleteBuildParams) { ls.writeLock(logger, true) defer ls.writeUnlock(logger) @@ -1212,8 +1192,7 @@ func (ls *INOLanguageServer) CopyFullBuildResults(logger jsonrpc.FunctionLogger, } } -// PublishDiagnosticsNotifFromClangd publishes a diagnostics if notified from Clangd -func (ls *INOLanguageServer) PublishDiagnosticsNotifFromClangd(logger jsonrpc.FunctionLogger, clangParams *lsp.PublishDiagnosticsParams) { +func (ls *INOLanguageServer) publishDiagnosticsNotifFromClangd(logger jsonrpc.FunctionLogger, clangParams *lsp.PublishDiagnosticsParams) { if ls.config.DisableRealTimeDiagnostics { logger.Logf("Ignored by configuration") return @@ -1293,8 +1272,7 @@ func (ls *INOLanguageServer) PublishDiagnosticsNotifFromClangd(logger jsonrpc.Fu } } -// TextDocumentRenameReqFromIDE handles a request from the IDE to rename TextDocument -func (ls *INOLanguageServer) TextDocumentRenameReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.RenameParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { +func (ls *INOLanguageServer) textDocumentRenameReqFromIDE(ctx context.Context, logger jsonrpc.FunctionLogger, ideParams *lsp.RenameParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { ls.writeLock(logger, false) defer ls.writeUnlock(logger) @@ -1340,8 +1318,7 @@ func (ls *INOLanguageServer) ideURIIsPartOfTheSketch(ideURI lsp.DocumentURI) boo return res } -// ProgressNotifFromClangd handles a progress request from clangd -func (ls *INOLanguageServer) ProgressNotifFromClangd(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { +func (ls *INOLanguageServer) progressNotifFromClangd(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { var token string if err := json.Unmarshal(progress.Token, &token); err != nil { logger.Logf("error decoding progress token: %s", err) @@ -1362,8 +1339,7 @@ func (ls *INOLanguageServer) ProgressNotifFromClangd(logger jsonrpc.FunctionLogg } } -// WindowWorkDoneProgressCreateReqFromClangd handles a progress create request from clangd -func (ls *INOLanguageServer) WindowWorkDoneProgressCreateReqFromClangd(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { +func (ls *INOLanguageServer) windowWorkDoneProgressCreateReqFromClangd(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { var token string if err := json.Unmarshal(params.Token, &token); err != nil { logger.Logf("error decoding progress token: %s", err) @@ -1373,8 +1349,7 @@ func (ls *INOLanguageServer) WindowWorkDoneProgressCreateReqFromClangd(ctx conte return nil } -// SetTraceNotifFromIDE gets a notification from the IDE to Set Trace to parameters -func (ls *INOLanguageServer) SetTraceNotifFromIDE(logger jsonrpc.FunctionLogger, params *lsp.SetTraceParams) { +func (ls *INOLanguageServer) setTraceNotifFromIDE(logger jsonrpc.FunctionLogger, params *lsp.SetTraceParams) { logger.Logf("Notification level set to: %s", params.Value) ls.Clangd.conn.SetTrace(params) } diff --git a/ls/lsp_client_clangd.go b/ls/lsp_client_clangd.go index c8db132..f21f4d1 100644 --- a/ls/lsp_client_clangd.go +++ b/ls/lsp_client_clangd.go @@ -108,7 +108,7 @@ func (client *clangdLSPClient) WindowShowDocument(context.Context, jsonrpc.Funct // WindowWorkDoneProgressCreate is not implemented func (client *clangdLSPClient) WindowWorkDoneProgressCreate(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.WorkDoneProgressCreateParams) *jsonrpc.ResponseError { - return client.ls.WindowWorkDoneProgressCreateReqFromClangd(ctx, logger, params) + return client.ls.windowWorkDoneProgressCreateReqFromClangd(ctx, logger, params) } // ClientRegisterCapability is not implemented @@ -143,7 +143,7 @@ func (client *clangdLSPClient) WorkspaceCodeLensRefresh(context.Context, jsonrpc // Progress sends a Progress notification func (client *clangdLSPClient) Progress(logger jsonrpc.FunctionLogger, progress *lsp.ProgressParams) { - client.ls.ProgressNotifFromClangd(logger, progress) + client.ls.progressNotifFromClangd(logger, progress) } // LogTrace is not implemented @@ -168,5 +168,5 @@ func (client *clangdLSPClient) TelemetryEvent(jsonrpc.FunctionLogger, json.RawMe // TextDocumentPublishDiagnostics sends a notification to Publish Dignostics func (client *clangdLSPClient) TextDocumentPublishDiagnostics(logger jsonrpc.FunctionLogger, params *lsp.PublishDiagnosticsParams) { - go client.ls.PublishDiagnosticsNotifFromClangd(logger, params) + go client.ls.publishDiagnosticsNotifFromClangd(logger, params) } diff --git a/ls/lsp_server_ide.go b/ls/lsp_server_ide.go index b9960d2..b5e8ff2 100644 --- a/ls/lsp_server_ide.go +++ b/ls/lsp_server_ide.go @@ -40,12 +40,12 @@ func (server *IDELSPServer) Run() { // Initialize sends an initilize request func (server *IDELSPServer) Initialize(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.InitializeParams) (*lsp.InitializeResult, *jsonrpc.ResponseError) { - return server.ls.InitializeReqFromIDE(ctx, logger, params) + return server.ls.initializeReqFromIDE(ctx, logger, params) } // Shutdown sends a shutdown request func (server *IDELSPServer) Shutdown(ctx context.Context, logger jsonrpc.FunctionLogger) *jsonrpc.ResponseError { - return server.ls.ShutdownReqFromIDE(ctx, logger) + return server.ls.shutdownReqFromIDE(ctx, logger) } // WorkspaceSymbol is not implemented @@ -80,7 +80,7 @@ func (server *IDELSPServer) TextDocumentWillSaveWaitUntil(ctx context.Context, l // TextDocumentCompletion is not implemented func (server *IDELSPServer) TextDocumentCompletion(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CompletionParams) (*lsp.CompletionList, *jsonrpc.ResponseError) { - return server.ls.TextDocumentCompletionReqFromIDE(ctx, logger, params) + return server.ls.textDocumentCompletionReqFromIDE(ctx, logger, params) } // CompletionItemResolve is not implemented @@ -90,12 +90,12 @@ func (server *IDELSPServer) CompletionItemResolve(ctx context.Context, logger js // TextDocumentHover sends a request to hover a text document func (server *IDELSPServer) TextDocumentHover(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.HoverParams) (*lsp.Hover, *jsonrpc.ResponseError) { - return server.ls.TextDocumentHoverReqFromIDE(ctx, logger, params) + return server.ls.textDocumentHoverReqFromIDE(ctx, logger, params) } // TextDocumentSignatureHelp requests help for text document signature func (server *IDELSPServer) TextDocumentSignatureHelp(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.SignatureHelpParams) (*lsp.SignatureHelp, *jsonrpc.ResponseError) { - return server.ls.TextDocumentSignatureHelpReqFromIDE(ctx, logger, params) + return server.ls.textDocumentSignatureHelpReqFromIDE(ctx, logger, params) } // TextDocumentDeclaration is not implemented @@ -105,17 +105,17 @@ func (server *IDELSPServer) TextDocumentDeclaration(ctx context.Context, logger // TextDocumentDefinition sends a request to define a text document func (server *IDELSPServer) TextDocumentDefinition(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { - return server.ls.TextDocumentDefinitionReqFromIDE(ctx, logger, params) + return server.ls.textDocumentDefinitionReqFromIDE(ctx, logger, params) } // TextDocumentTypeDefinition sends a request to define a type for the text document func (server *IDELSPServer) TextDocumentTypeDefinition(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.TypeDefinitionParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { - return server.ls.TextDocumentTypeDefinitionReqFromIDE(ctx, logger, params) + return server.ls.textDocumentTypeDefinitionReqFromIDE(ctx, logger, params) } // TextDocumentImplementation sends a request to implement a text document func (server *IDELSPServer) TextDocumentImplementation(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.ImplementationParams) ([]lsp.Location, []lsp.LocationLink, *jsonrpc.ResponseError) { - return server.ls.TextDocumentImplementationReqFromIDE(ctx, logger, params) + return server.ls.textDocumentImplementationReqFromIDE(ctx, logger, params) } // TextDocumentReferences is not implemented @@ -125,17 +125,17 @@ func (server *IDELSPServer) TextDocumentReferences(ctx context.Context, logger j // TextDocumentDocumentHighlight sends a request to highlight a text document func (server *IDELSPServer) TextDocumentDocumentHighlight(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentHighlightParams) ([]lsp.DocumentHighlight, *jsonrpc.ResponseError) { - return server.ls.TextDocumentDocumentHighlightReqFromIDE(ctx, logger, params) + return server.ls.textDocumentDocumentHighlightReqFromIDE(ctx, logger, params) } // TextDocumentDocumentSymbol sends a request for text document symbol func (server *IDELSPServer) TextDocumentDocumentSymbol(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentSymbolParams) ([]lsp.DocumentSymbol, []lsp.SymbolInformation, *jsonrpc.ResponseError) { - return server.ls.TextDocumentDocumentSymbolReqFromIDE(ctx, logger, params) + return server.ls.textDocumentDocumentSymbolReqFromIDE(ctx, logger, params) } // TextDocumentCodeAction sends a request for text document code action func (server *IDELSPServer) TextDocumentCodeAction(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.CodeActionParams) ([]lsp.CommandOrCodeAction, *jsonrpc.ResponseError) { - return server.ls.TextDocumentCodeActionReqFromIDE(ctx, logger, params) + return server.ls.textDocumentCodeActionReqFromIDE(ctx, logger, params) } // CodeActionResolve is not implemented @@ -175,12 +175,12 @@ func (server *IDELSPServer) TextDocumentColorPresentation(ctx context.Context, l // TextDocumentFormatting sends a request to format a text document func (server *IDELSPServer) TextDocumentFormatting(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { - return server.ls.TextDocumentFormattingReqFromIDE(ctx, logger, params) + return server.ls.textDocumentFormattingReqFromIDE(ctx, logger, params) } // TextDocumentRangeFormatting sends a request to format the range a text document func (server *IDELSPServer) TextDocumentRangeFormatting(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.DocumentRangeFormattingParams) ([]lsp.TextEdit, *jsonrpc.ResponseError) { - return server.ls.TextDocumentRangeFormattingReqFromIDE(ctx, logger, params) + return server.ls.textDocumentRangeFormattingReqFromIDE(ctx, logger, params) } // TextDocumentOnTypeFormatting is not implemented @@ -190,7 +190,7 @@ func (server *IDELSPServer) TextDocumentOnTypeFormatting(ctx context.Context, lo // TextDocumentRename sends a request to rename a text document func (server *IDELSPServer) TextDocumentRename(ctx context.Context, logger jsonrpc.FunctionLogger, params *lsp.RenameParams) (*lsp.WorkspaceEdit, *jsonrpc.ResponseError) { - return server.ls.TextDocumentRenameReqFromIDE(ctx, logger, params) + return server.ls.textDocumentRenameReqFromIDE(ctx, logger, params) } // TextDocumentFoldingRange is not implemented @@ -257,17 +257,17 @@ func (server *IDELSPServer) Progress(logger jsonrpc.FunctionLogger, params *lsp. // Initialized sends an initialized notification func (server *IDELSPServer) Initialized(logger jsonrpc.FunctionLogger, params *lsp.InitializedParams) { - server.ls.InitializedNotifFromIDE(logger, params) + server.ls.initializedNotifFromIDE(logger, params) } // Exit sends an exit notification func (server *IDELSPServer) Exit(logger jsonrpc.FunctionLogger) { - server.ls.ExitNotifFromIDE(logger) + server.ls.exitNotifFromIDE(logger) } // SetTrace sends a set trace notification func (server *IDELSPServer) SetTrace(logger jsonrpc.FunctionLogger, params *lsp.SetTraceParams) { - server.ls.SetTraceNotifFromIDE(logger, params) + server.ls.setTraceNotifFromIDE(logger, params) } // WindowWorkDoneProgressCancel is not implemented @@ -314,12 +314,12 @@ func (server *IDELSPServer) WorkspaceDidDeleteFiles(logger jsonrpc.FunctionLogge // TextDocumentDidOpen sends a notification the a text document is open func (server *IDELSPServer) TextDocumentDidOpen(logger jsonrpc.FunctionLogger, params *lsp.DidOpenTextDocumentParams) { - server.ls.TextDocumentDidOpenNotifFromIDE(logger, params) + server.ls.textDocumentDidOpenNotifFromIDE(logger, params) } // TextDocumentDidChange sends a notification the a text document has changed func (server *IDELSPServer) TextDocumentDidChange(logger jsonrpc.FunctionLogger, params *lsp.DidChangeTextDocumentParams) { - server.ls.TextDocumentDidChangeNotifFromIDE(logger, params) + server.ls.textDocumentDidChangeNotifFromIDE(logger, params) } // TextDocumentWillSave is not implemented @@ -329,12 +329,12 @@ func (server *IDELSPServer) TextDocumentWillSave(logger jsonrpc.FunctionLogger, // TextDocumentDidSave sends a notification the a text document has been saved func (server *IDELSPServer) TextDocumentDidSave(logger jsonrpc.FunctionLogger, params *lsp.DidSaveTextDocumentParams) { - server.ls.TextDocumentDidSaveNotifFromIDE(logger, params) + server.ls.textDocumentDidSaveNotifFromIDE(logger, params) } // TextDocumentDidClose sends a notification the a text document has been closed func (server *IDELSPServer) TextDocumentDidClose(logger jsonrpc.FunctionLogger, params *lsp.DidCloseTextDocumentParams) { - server.ls.TextDocumentDidCloseNotifFromIDE(logger, params) + server.ls.textDocumentDidCloseNotifFromIDE(logger, params) } // DidCompleteBuildParams is a custom notification from the Arduino IDE, sent @@ -352,6 +352,6 @@ func (server *IDELSPServer) ArduinoBuildCompleted(logger jsonrpc.FunctionLogger, if err := json.Unmarshal(raw, ¶ms); err != nil { logger.Logf("ERROR decoding DidCompleteBuildParams: %s", err) } else { - server.ls.FullBuildCompletedFromIDE(logger, ¶ms) + server.ls.fullBuildCompletedFromIDE(logger, ¶ms) } }