| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "log" |
| "os" |
| "path/filepath" |
| |
| "github.com/sourcegraph/jsonrpc2" |
| |
| "fidl-lsp/analysis" |
| "fidl-lsp/langserver" |
| ) |
| |
| var ( |
| fuchsiaDir = os.Getenv("FUCHSIA_DIR") |
| outDir = fuchsiaDir + "/out/default/" |
| fidlProjectPath = outDir + "fidl_project.json" |
| toolsPath = fuchsiaDir + "/out/default/host_x64/" |
| fidlLintPath = toolsPath + "fidl-lint" |
| ) |
| |
| type stdrwc struct{} |
| |
| func (stdrwc) Read(p []byte) (int, error) { |
| return os.Stdin.Read(p) |
| } |
| |
| func (stdrwc) Write(p []byte) (int, error) { |
| return os.Stdout.Write(p) |
| } |
| |
| func (stdrwc) Close() error { |
| if err := os.Stdin.Close(); err != nil { |
| return err |
| } |
| return os.Stdout.Close() |
| } |
| |
| func main() { |
| ctx, cancel := context.WithCancel(context.Background()) |
| defer cancel() |
| |
| trace := log.New(os.Stderr, "[LSP] ", log.Lshortfile) |
| logOpt := jsonrpc2.LogMessages(trace) |
| |
| // Assume that `fidlc` and `fidl-format` are distributed in the same |
| // platform-specific directory as this server binary, so we can find them in |
| // this directory. |
| ex, err := os.Executable() |
| if err != nil { |
| trace.Fatalf("Failed to get current working directory: %s\n", err) |
| } |
| cwd := filepath.Dir(ex) |
| |
| analyzer := analysis.NewAnalyzer( |
| // Config from VSCode will be loaded via LSP to replace this config. |
| analysis.Config{ |
| BuildRootDir: fuchsiaDir, |
| FidlcPath: fmt.Sprintf("%s/fidlc", cwd), |
| FidlFormatPath: fmt.Sprintf("%s/fidl-format", cwd), |
| FidlLintPath: fidlLintPath, |
| }, |
| ) |
| |
| handler := langserver.NewLangHandler( |
| langserver.NewDefaultConfig(fidlProjectPath), |
| trace, |
| analyzer, |
| ) |
| server := langserver.LspServer{handler} |
| |
| // Setup a new Conn over stdio |
| trace.Println("setting up a new connection") |
| conn := jsonrpc2.NewConn( |
| ctx, |
| jsonrpc2.NewBufferedStream(stdrwc{}, jsonrpc2.VSCodeObjectCodec{}), |
| server, |
| logOpt, |
| ) |
| defer conn.Close() |
| |
| <-conn.DisconnectNotify() |
| } |