Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Csharp lsp #52

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmd/acme-lsp/acme-lsp
cmd/L/L
cmd/Lone/Lone
bin/*
guide
5 changes: 5 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

go build -o ./bin ./cmd/L
go build -o ./bin ./cmd/acme-lsp
go build -o ./bin ./cmd/acmefocused
15 changes: 14 additions & 1 deletion cmd/L/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,15 @@ func usage() {
os.Exit(2)
}

var logger = log.Default()

func main() {
flag.Usage = usage
cfg := cmd.Setup(config.ProxyFlags)

logger.SetFlags(log.Llongfile)
logger.SetPrefix("L: ")

err := run(cfg, flag.Args())
if err != nil {
log.Fatalf("%v", err)
Expand All @@ -128,12 +133,19 @@ func run(cfg *config.Config, args []string) error {
if err != nil {
return fmt.Errorf("dial failed: %v", err)
}
defer conn.Close()

logger.Print(fmt.Sprintf("net.Dial: %s, %s", cfg.ProxyNetwork, cfg.ProxyAddress))
defer func() {
conn.Close()
logger.Print("L connection closed")
}()

stream := jsonrpc2.NewHeaderStream(conn, conn)
ctx, rpc, server := proxy.NewClient(ctx, stream, nil)
go rpc.Run(ctx)

logger.Print("started JSONN RPC")

ver, err := server.Version(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -204,6 +216,7 @@ func run(cfg *config.Config, args []string) error {
return rc.Completion(ctx, len(args) > 0 && args[0] == "-e")
case "def":
args = args[1:]

return rc.Definition(ctx, len(args) > 0 && args[0] == "-p")
case "fmt":
return rc.OrganizeImportsAndFormat(ctx)
Expand Down
5 changes: 5 additions & 0 deletions cmd/acme-lsp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ func usage() {
os.Exit(2)
}

var logger = log.Default()

func main() {
flag.Usage = usage
cfg := cmd.Setup(config.LangServerFlags | config.ProxyFlags)
logger.SetFlags(log.Llongfile)
logger.SetPrefix("acme-lsp: ")

ctx := context.Background()
app, err := NewApplication(ctx, cfg, flag.Args())
Expand Down Expand Up @@ -99,6 +103,7 @@ func NewApplication(ctx context.Context, cfg *config.Config, args []string) (*Ap
func (app *Application) Run(ctx context.Context) error {
go app.fm.Run()

log.Print("start acmelsp ListenAndServeProxy")
err := acmelsp.ListenAndServeProxy(ctx, app.cfg, app.ss, app.fm)
if err != nil {
return fmt.Errorf("proxy failed: %v", err)
Expand Down
10 changes: 5 additions & 5 deletions internal/golang_org_x_tools.update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ COMMIT=952e2c076240
rm -rf $DIR
git clone $REPO
(
cd tools
git checkout $COMMIT
cd tools
git checkout $COMMIT
)

mkdir $DIR
Expand All @@ -23,9 +23,9 @@ mv tools/internal/telemetry $DIR/telemetry
mv tools/internal/xcontext $DIR/xcontext

(
cd tools
echo "Packages in this directory is copied from golang.org/x/tools/internal (commit $COMMIT)."
#git show -s --format='(commit %h on %ci).'
cd tools
echo "Packages in this directory is copied from golang.org/x/tools/internal (commit $COMMIT)."
#git show -s --format='(commit %h on %ci).'
) > $DIR/README.txt

find $DIR -name '*.go' | xargs sed -i 's!golang.org/x/tools/internal!github.com/fhs/acme-lsp/internal/golang_org_x_tools!'
Expand Down
6 changes: 6 additions & 0 deletions internal/golang_org_x_tools/jsonrpc2/jsonrpc2.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
Method: method,
Params: jsonParams,
}

// marshal the request now it is complete
data, err := json.Marshal(request)
if err != nil {
Expand All @@ -147,6 +148,7 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
for _, h := range c.handlers {
ctx = h.Request(ctx, c, Send, request)
}

// we have to add ourselves to the pending map before we send, otherwise we
// are racing the response
rchan := make(chan *WireResponse)
Expand Down Expand Up @@ -177,16 +179,19 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
for _, h := range c.handlers {
ctx = h.Response(ctx, c, Receive, response)
}

// is it an error response?
if response.Error != nil {
return response.Error
}
if result == nil || response.Result == nil {
return nil
}

if err := json.Unmarshal(*response.Result, result); err != nil {
return fmt.Errorf("unmarshalling result: %v", err)
}

return nil
case <-ctx.Done():
// allow the handler to propagate the cancel
Expand Down Expand Up @@ -261,6 +266,7 @@ func (r *Request) Reply(ctx context.Context, result interface{}, err error) erro
if err != nil {
return err
}

for _, h := range r.conn.handlers {
ctx = h.Response(ctx, r.conn, Send, response)
}
Expand Down
11 changes: 9 additions & 2 deletions internal/lsp/acmelsp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ func (h *clientHandler) ShowMessage(ctx context.Context, params *protocol.ShowMe
return nil
}

func (h *clientHandler) Metadata(ctx context.Context, params *protocol.MetadataParams) error {
log.Printf("LSP Metadata, params: %v\n", params)
return nil
}

func (h *clientHandler) LogMessage(ctx context.Context, params *protocol.LogMessageParams) error {
if h.cfg.Logger != nil {
h.cfg.Logger.Printf("%v: %v\n", params.Type, params.Message)
Expand Down Expand Up @@ -121,7 +126,7 @@ func (c *Client) init(conn net.Conn, cfg *ClientConfig) error {
if cfg.RPCTrace {
stream = protocol.LoggingStream(stream, os.Stderr)
}
ctx, rpc, server := protocol.NewClient(ctx, stream, &clientHandler{
ctx, rpc, serverDispatcher := protocol.NewClient(ctx, stream, &clientHandler{
cfg: cfg,
hideDiag: cfg.HideDiag,
diagWriter: cfg.DiagWriter,
Expand All @@ -132,6 +137,8 @@ func (c *Client) init(conn net.Conn, cfg *ClientConfig) error {
if err != nil {
log.Printf("connection terminated: %v", err)
}

log.Printf("client RCP runs ")
}()

d, err := filepath.Abs(cfg.RootDirectory)
Expand Down Expand Up @@ -168,7 +175,7 @@ func (c *Client) init(conn net.Conn, cfg *ClientConfig) error {
if err := rpc.Notify(ctx, "initialized", &protocol.InitializedParams{}); err != nil {
return fmt.Errorf("initialized failed: %v", err)
}
c.Server = server
c.Server = serverDispatcher
c.initializeResult = &result
return nil
}
Expand Down
1 change: 1 addition & 0 deletions internal/lsp/acmelsp/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type Config struct {

// Server describes a LSP server.
type Server struct {
Name string
// Command that speaks LSP on stdin/stdout.
// Can be empty if Address is given.
Command []string
Expand Down
15 changes: 14 additions & 1 deletion internal/lsp/acmelsp/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import (
)

type Server struct {
conn net.Conn
Name string
conn net.Conn

Client *Client
}

Expand All @@ -30,6 +32,10 @@ func (s *Server) Close() {
}
}

func (s *Server) Conn() net.Conn {
return s.conn
}

func execServer(cs *config.Server, cfg *ClientConfig) (*Server, error) {
args := cs.Command

Expand Down Expand Up @@ -190,13 +196,17 @@ func NewServerSet(cfg *config.Config, diagWriter DiagnosticsWriter) (*ServerSet,
}
logger = log.New(f, "", log.LstdFlags)
}

data = append(data, &ServerInfo{
Server: cs,
FilenameHandler: &cfg.FilenameHandlers[i],
Re: re,
Logger: logger,
})

log.Printf("Add %#v server to serverSet ", cs)
}

return &ServerSet{
Data: data,
diagWriter: diagWriter,
Expand Down Expand Up @@ -236,6 +246,9 @@ func (ss *ServerSet) StartForFile(filename string) (*Server, bool, error) {
if err != nil {
return nil, false, err
}

srv.Name = info.Name

return srv, true, err
}

Expand Down
3 changes: 3 additions & 0 deletions internal/lsp/acmelsp/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log"

"sync"

"github.com/fhs/acme-lsp/internal/acme"
Expand Down Expand Up @@ -82,6 +83,7 @@ func (fm *FileManager) Run() {
if err := fm.didSave(ev.ID, ev.Name); err != nil {
log.Printf("didSave failed in file manager: %v", err)
}

if fm.cfg.FormatOnPut {
if err := fm.format(ev.ID, ev.Name); err != nil && Verbose {
log.Printf("Format failed in file manager: %v", err)
Expand Down Expand Up @@ -193,6 +195,7 @@ func (fm *FileManager) didSave(winid int, name string) error {
if err != nil {
return err
}

return lsp.DidSave(context.Background(), c, name)
})
}
Expand Down
90 changes: 90 additions & 0 deletions internal/lsp/acmelsp/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Package acmelsp implements the core of acme-lsp commands.
package acmelsp

import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/fhs/acme-lsp/internal/lsp/protocol"
)

//metdata is implemented due to the https://github.com/OmniSharp/omnisharp-roslyn/issues/2238

func convertFilePath(p string) (path string) {
path = strings.Replace(p, "$metadata$", fmt.Sprintf("%s/csharp-metadata/", os.TempDir()), 1) //os.TempDir
return
}

func GetMetaParas(s string) (*protocol.MetadataParams, bool) { //
out := &protocol.MetadataParams{TimeOut: 5000}
parts := strings.Split(s, "/Assembly/")

if len(parts) < 2 {
return nil, false
}

pName := strings.TrimPrefix(parts[0], "file:///%24metadata%24/Project/")

out.ProjectName = pName

parts = strings.Split(parts[1], "/Symbol/")

if len(parts) != 2 {
return nil, false
}

assemblyName := strings.Replace(parts[0], "/", ".", -1)

out.AssemblyName = assemblyName

typeName := strings.Replace(strings.TrimSuffix(parts[1], ".cs"), "/", ".", -1)

out.TypeName = typeName

return out, true

}

func (rc *RemoteCmd) localizeMetadata(ctx context.Context, uri string) (string, error) {
p, ok := GetMetaParas(uri)
if !ok {
return "", fmt.Errorf("failed to parse URI to MetaParas")
}
// server over here is the acme-lsp server
src, err := rc.server.Metadata(ctx, p)

if err != nil {
return "", fmt.Errorf("failed to retrive metatdata of uri: %s, with err: %w", uri, err)
}

key := src.SourceName

if v, ok := rc.metadataSet[key]; ok {
return v, nil
}

path := convertFilePath(key)

if err := os.MkdirAll(filepath.Dir(path), 0770); err != nil {
return "", fmt.Errorf("failed to create dir %s for metatdata of uri: %s to disk, with err: %v", filepath.Dir(path), uri, err)
}

f, err := os.Create(path) // creates a file at current directory
if err != nil {
return "", fmt.Errorf("failed to create file for metatdata of uri: %s to disk, with err: %v", uri, err)
}

defer f.Close()

if err := ioutil.WriteFile(path, []byte(src.Source), 0644); err != nil {
return "", fmt.Errorf("failed to write metatdata of uri: %s to disk, with err: %v", uri, err)
}

rc.metadataSet[key] = path
return path, nil

}
Loading