Exemplo n.º 1
0
 public override RpcResult DidSaveTextDocument(DidSaveTextDocumentParams args)
 {
     return(RpcResult.Error(new ResponseError
     {
         code = (int)ErrorCodes.RequestFailed,
         message = "Not supported"
     }));
 }
Exemplo n.º 2
0
 /**
  * The result type LocationLink[] got introduced with version 3.14.0
  * and depends on the corresponding client capability textDocument.implementation.linkSupport.
  */
 public override RpcResult GotoImplementation(ImplementationParams args)
 {
     return(RpcResult.Error(new ResponseError
     {
         code = (int)ErrorCodes.RequestFailed,
         message = "Not supported"
     }));
 }
Exemplo n.º 3
0
        public override RpcResult Exit()
        {
            if (processId != null)
            {
                Environment.Exit(0);
            }

            return(RpcResult.Success());
        }
Exemplo n.º 4
0
        private RpcResult CallRpcMethod(string name, JToken @params)
        {
            if (double.TryParse(name, out _))
            {
                return(RpcResult.Error(new ResponseError
                {
                    code = (int)ErrorCodes.InvalidRequest,
                    message = ""
                }));
            }

            foreach (var service in services)
            {
                foreach (var method in service.GetType().GetMethods())
                {
                    if (IsAllowedToInvoke(method, name))
                    {
                        object[] args = null;
                        var      pms  = method.GetParameters();
                        if (pms.Length > 0)
                        {
                            try
                            {
                                args = new[] { @params.ToObject(pms[0].ParameterType) };
                            }
#if BHLSP_DEBUG
                            catch (Exception e)
                            {
                                BHLSPLogger.WriteLine(e);
#else
                            catch
                            {
#endif
                                return(RpcResult.Error(new ResponseError
                                {
                                    code = (int)ErrorCodes.InvalidParams,
                                    message = ""
                                }));
                            }
                        }

                        return((RpcResult)method.Invoke(service, args));
                    }
                }
            }

            return(RpcResult.Error(new ResponseError
            {
                code = (int)ErrorCodes.MethodNotFound,
                message = "Method not found"
            }));
        }
Exemplo n.º 5
0
        public override RpcResult DidChangeTextDocument(DidChangeTextDocumentParams args)
        {
            if (BHLSPWorkspace.self.FindDocument(args.textDocument.uri) is BHLSPTextDocument document)
            {
                if (BHLSPWorkspace.self.syncKind == TextDocumentSyncKind.Full)
                {
                    foreach (var contentChanges in args.contentChanges)
                    {
                        document.Sync(contentChanges.text);
                    }
                }
                else if (BHLSPWorkspace.self.syncKind == TextDocumentSyncKind.Incremental)
                {
                    //TODO: ...
                }
            }

            return(RpcResult.Success());
        }
Exemplo n.º 6
0
        public override RpcResult SemanticTokensFull(SemanticTokensParams args)
        {
            BHLSPWorkspace.self.TryAddDocument(args.textDocument.uri);
            var document = BHLSPWorkspace.self.FindDocument(args.textDocument.uri);

            if (document is BHLTextDocument bhldocument)
            {
                return(RpcResult.Success(new SemanticTokens
                {
                    data = bhldocument.DataSemanticTokens.ToArray()
                }));
            }

            if (document is JSTextDocument /*jsdocument*/)
            {
                return(RpcResult.Success(new SemanticTokens
                {
                    data = new uint[0]
                }));
            }

            return(RpcResult.Success());
        }
Exemplo n.º 7
0
        public override RpcResult Hover(TextDocumentPositionParams args)
        {
            BHLSPWorkspace.self.TryAddDocument(args.textDocument.uri);
            if (BHLSPWorkspace.self.FindDocument(args.textDocument.uri) is BHLTextDocument document)
            {
                int line      = (int)args.position.line;
                int character = (int)args.position.character;

                int idx = document.GetIndex(line, character);

                bhlParser.CallExpContext callExp = null;

                foreach (IParseTree node in BHLSPUtil.DFS(document.ToParser().program()))
                {
                    if (node is ParserRuleContext prc)
                    {
                        if (prc.Start.StartIndex <= idx && idx <= prc.Stop.StopIndex)
                        {
                            callExp = prc as bhlParser.CallExpContext;
                            break;
                        }
                    }
                }

                bhlParser.FuncDeclContext funcDecl = null;

                if (callExp != null)
                {
                    string callExpName = callExp.NAME().GetText();

                    foreach (var doc in BHLSPWorkspace.self.ForEachBhlImports(document))
                    {
                        if (doc.FuncDecls.ContainsKey(callExpName))
                        {
                            funcDecl = doc.FuncDecls[callExpName];
                            break;
                        }
                    }
                }

                if (funcDecl != null)
                {
                    string label = funcDecl.NAME().GetText() + "(";

                    List <ParameterInformation> funcParameters = BHLSPUtil.GetInfoParams(funcDecl);

                    if (funcParameters.Count > 0)
                    {
                        for (int k = 0; k < funcParameters.Count; k++)
                        {
                            var funcParameter = funcParameters[k];
                            label += funcParameter.label.Value;
                            if (k != funcParameters.Count - 1)
                            {
                                label += ", ";
                            }
                        }
                    }
                    else
                    {
                        label += "<no parameters>";
                    }

                    label += ")";

                    if (funcDecl.retType() is bhlParser.RetTypeContext retType)
                    {
                        label += ":";

                        var types = retType.type();
                        for (int n = 0; n < types.Length; n++)
                        {
                            var t = types[n];
                            if (t.exception != null)
                            {
                                continue;
                            }

                            label += t.NAME().GetText() + " ";
                        }
                    }
                    else
                    {
                        label += ":void";
                    }

                    return(RpcResult.Success(new Hover
                    {
                        contents = new MarkupContent
                        {
                            kind = "plaintext",
                            value = label
                        }
                    }));
                }
            }

            return(RpcResult.Success());
        }
Exemplo n.º 8
0
        /**
         * The result type LocationLink[] got introduced with version 3.14.0
         * and depends on the corresponding client capability textDocument.definition.linkSupport.
         */
        public override RpcResult GotoDefinition(DefinitionParams args)
        {
            BHLSPWorkspace.self.TryAddDocument(args.textDocument.uri);
            if (BHLSPWorkspace.self.FindDocument(args.textDocument.uri) is BHLTextDocument document)
            {
                int line      = (int)args.position.line;
                int character = (int)args.position.character;

                int idx = document.GetIndex(line, character);

                bhlParser.FuncDeclContext funcDecl            = null;
                BHLTextDocument           funcDeclBhlDocument = null;

                bhlParser.CallExpContext      callExp      = null;
                bhlParser.MemberAccessContext memberAccess = null;
                bhlParser.TypeContext         type         = null;
                bhlParser.StatementContext    statement    = null;

                foreach (IParseTree node in BHLSPUtil.DFS(document.ToParser().program()))
                {
                    if (node is ParserRuleContext prc)
                    {
                        if (prc.Start.StartIndex <= idx && idx <= prc.Stop.StopIndex)
                        {
                            funcDecl     = prc as bhlParser.FuncDeclContext;
                            callExp      = prc as bhlParser.CallExpContext;
                            memberAccess = prc as bhlParser.MemberAccessContext;
                            type         = prc as bhlParser.TypeContext;
                            statement    = prc as bhlParser.StatementContext;
                            break;
                        }
                    }
                }

                if (funcDecl == null)
                {
                    string classTypeName   = string.Empty;
                    string memberClassName = string.Empty;

                    if (type?.NAME() != null)
                    {
                        classTypeName = type.NAME().GetText();
                    }
                    else if (memberAccess != null)
                    {
                        bhlParser.CallExpContext  callExpMemberAccess        = null;
                        bhlParser.FuncDeclContext memberAccessParentFuncDecl = null;

                        memberClassName = memberAccess.NAME().GetText();

                        for (RuleContext parent = memberAccess.Parent; parent != null; parent = parent.Parent)
                        {
                            if (callExpMemberAccess == null && parent is bhlParser.CallExpContext)
                            {
                                callExpMemberAccess = parent as bhlParser.CallExpContext;
                            }

                            if (parent is bhlParser.FuncDeclContext)
                            {
                                memberAccessParentFuncDecl = parent as bhlParser.FuncDeclContext;
                                break;
                            }
                        }

                        if (callExpMemberAccess != null)
                        {
                            string callExpMemberAccessName = callExpMemberAccess.NAME().GetText();

                            if (memberAccessParentFuncDecl?.NAME() != null)
                            {
                                foreach (IParseTree node in BHLSPUtil.DFS(memberAccessParentFuncDecl))
                                {
                                    if (node is bhlParser.FuncParamDeclareContext funcParamDeclare)
                                    {
                                        bhlParser.TypeContext funcParamDeclareType = funcParamDeclare.type();
                                        if (funcParamDeclareType.funcType() != null || funcParamDeclareType.ARR() != null)
                                        {
                                            continue;
                                        }

                                        if (funcParamDeclare.NAME()?.GetText() == callExpMemberAccessName)
                                        {
                                            classTypeName = funcParamDeclareType.GetText();
                                            break;
                                        }
                                    }

                                    if (node is bhlParser.VarDeclareContext varDeclare && varDeclare?.NAME().GetText() == callExpMemberAccessName)
                                    {
                                        classTypeName = varDeclare.type().NAME().GetText();
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(classTypeName))
                    {
                        bhlParser.ClassDeclContext classDecl            = null;
                        BHLTextDocument            classDeclBhlDocument = null;

                        foreach (var doc in BHLSPWorkspace.self.ForEachBhlImports(document))
                        {
                            if (doc.ClassDecls.ContainsKey(classTypeName))
                            {
                                classDecl            = doc.ClassDecls[classTypeName];
                                classDeclBhlDocument = doc;
                                break;
                            }
                        }

                        if (classDecl != null)
                        {
                            bhlParser.ClassMemberContext classMember = null;

                            if (!string.IsNullOrEmpty(memberClassName))
                            {
                                foreach (var classMemberContext in classDecl.classBlock().classMembers().classMember())
                                {
                                    if (classMemberContext.funcDecl()?.NAME()?.GetText() != null)
                                    {
                                        if (classMemberContext.funcDecl().NAME().GetText() == memberClassName)
                                        {
                                            classMember = classMemberContext;
                                            break;
                                        }
                                    }

                                    if (classMemberContext.varDeclare()?.NAME()?.GetText() != null)
                                    {
                                        if (classMemberContext.varDeclare().NAME().GetText() == memberClassName)
                                        {
                                            classMember = classMemberContext;
                                            break;
                                        }
                                    }
                                }
                            }

                            int classDeclIdx = classMember?.Start.StartIndex ?? classDecl.Start.StartIndex;
                            var start        = classDeclBhlDocument.GetLineColumn(classDeclIdx);
                            var startPos     = new Position {
                                line = (uint)start.Item1, character = (uint)start.Item2
                            };

                            return(RpcResult.Success(new Location
                            {
                                uri = classDeclBhlDocument.uri,
                                range = new Range
                                {
                                    start = startPos,
                                    end = startPos
                                }
                            }));
                        }
                    }

                    if (callExp != null)
                    {
                        string callExpName = callExp.NAME().GetText();

                        foreach (var doc in BHLSPWorkspace.self.ForEachBhlImports(document))
                        {
                            if (doc.FuncDecls.ContainsKey(callExpName))
                            {
                                funcDecl            = doc.FuncDecls[callExpName];
                                funcDeclBhlDocument = doc;
                                break;
                            }
                        }
                    }

                    if (statement != null && funcDecl == null)
                    {
                        string funcName = string.Empty;

                        string          pattern = @"([a-zA-Z_][a-zA-Z_0-9]*)(\({1}.*?)";
                        MatchCollection matches = Regex.Matches(statement.GetText(), pattern, RegexOptions.Multiline);
                        for (int i = 0; i < matches.Count; i++)
                        {
                            var m = matches[i];
                            if (m.Groups.Count > 1)
                            {
                                Group g = m.Groups[1];
                                funcName = g.Value;
                                break;
                            }
                        }

                        if (!string.IsNullOrEmpty(funcName))
                        {
                            foreach (var doc in BHLSPWorkspace.self.ForEachBhlImports(document))
                            {
                                if (doc.FuncDecls.ContainsKey(funcName))
                                {
                                    funcDecl            = doc.FuncDecls[funcName];
                                    funcDeclBhlDocument = doc;
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    funcDeclBhlDocument = document;
                }

                if (funcDecl != null)
                {
                    var start    = funcDeclBhlDocument.GetLineColumn(funcDecl.Start.StartIndex);
                    var startPos = new Position {
                        line = (uint)start.Item1, character = (uint)start.Item2
                    };

                    return(RpcResult.Success(new Location
                    {
                        uri = funcDeclBhlDocument.uri,
                        range = new Range
                        {
                            start = startPos,
                            end = startPos
                        }
                    }));
                }
            }

            return(RpcResult.Success());
        }
Exemplo n.º 9
0
 public override RpcResult DidCloseTextDocument(DidCloseTextDocumentParams args)
 {
     return(RpcResult.Success());
 }
Exemplo n.º 10
0
 public override RpcResult DidOpenTextDocument(DidOpenTextDocumentParams args)
 {
     BHLSPWorkspace.self.TryAddDocument(args.textDocument.uri, args.textDocument.text);
     return(RpcResult.Success());
 }
Exemplo n.º 11
0
        public override RpcResult SignatureHelp(SignatureHelpParams args)
        {
            BHLSPWorkspace.self.TryAddDocument(args.textDocument.uri);
            if (BHLSPWorkspace.self.FindDocument(args.textDocument.uri) is BHLTextDocument document)
            {
                int line      = (int)args.position.line;
                int character = (int)args.position.character;

                int start = document.GetIndex(line);
                int stop  = document.GetIndex(line, character);
                var text  = document.text;

                var    txtLine         = text.Substring(start, stop - start);
                string funcName        = string.Empty;
                uint   activeParameter = 0;

                if (txtLine.IndexOf("func", StringComparison.Ordinal) == -1)
                {
                    string          pattern = @"[a-zA-Z_][a-zA-Z_0-9]*\({1}.*?";
                    MatchCollection matches = Regex.Matches(txtLine, pattern, RegexOptions.Multiline);
                    for (int i = matches.Count - 1; i >= 0; i--)
                    {
                        var m = matches[i];
                        if (m.Index < character)
                        {
                            string v   = m.Value;
                            int    len = v.Length - 1;

                            if (len > 0)
                            {
                                funcName = txtLine.Substring(m.Index, len);
                                var funcDeclStr = txtLine.Substring(m.Index, Math.Max(0, character - m.Index));
                                activeParameter = (uint)Math.Max(0, funcDeclStr.Split(',').Length - 1);
                                break;
                            }
                        }
                    }
                }

                bhlParser.FuncDeclContext funcDecl = null;
                if (!string.IsNullOrEmpty(funcName))
                {
                    foreach (var doc in BHLSPWorkspace.self.ForEachBhlImports(document))
                    {
                        if (doc.FuncDecls.ContainsKey(funcName))
                        {
                            funcDecl = doc.FuncDecls[funcName];
                            break;
                        }
                    }
                }

                if (funcDecl != null)
                {
                    SignatureInformation signInfo = GetFuncSignInfo(funcDecl);
                    signInfo.activeParameter = activeParameter;

                    var result = new SignatureHelp();
                    result.activeSignature = 0;
                    result.signatures      = new[] { signInfo };
                    result.activeParameter = signInfo.activeParameter;

                    return(RpcResult.Success(result));
                }
            }

            return(RpcResult.Success());
        }
Exemplo n.º 12
0
 public override RpcResult Shutdown()
 {
     BHLSPWorkspace.self.Shutdown();
     return(RpcResult.Success());
 }
Exemplo n.º 13
0
 public override RpcResult Initialized()
 {
     return(RpcResult.Success());
 }
Exemplo n.º 14
0
        public override RpcResult Initialize(InitializeParams args)
        {
            processId = args.processId;

            if (args.workspaceFolders != null)
            {
                for (int i = 0; i < args.workspaceFolders.Length; i++)
                {
                    BHLSPWorkspace.self.AddRoot(args.workspaceFolders[i].uri.LocalPath, true);
                }
            }
            else if (args.rootUri != null) // @deprecated in favour of `workspaceFolders`
            {
                BHLSPWorkspace.self.AddRoot(args.rootUri.LocalPath, true, false);
            }
            else if (!string.IsNullOrEmpty(args.rootPath)) // @deprecated in favour of `rootUri`.
            {
                BHLSPWorkspace.self.AddRoot(args.rootPath, true, false);
            }

            BHLSPWorkspace.self.Scan();

            ServerCapabilities capabilities = new ServerCapabilities();

            if (args.capabilities.textDocument != null)
            {
                if (args.capabilities.textDocument.synchronization != null)
                {
                    capabilities.textDocumentSync = new TextDocumentSyncOptions
                    {
                        openClose = true,                         //didOpen, didClose
                        change    = BHLSPWorkspace.self.syncKind, //didChange
                        save      = false                         //didSave
                    };
                }

                if (args.capabilities.textDocument.signatureHelp != null)
                {
                    capabilities.signatureHelpProvider = new SignatureHelpOptions {
                        triggerCharacters = new[] { "(", "," }
                    };
                }

                if (args.capabilities.textDocument.declaration != null)
                {
                    if (args.capabilities.textDocument.declaration.linkSupport != null)
                    {
                        BHLSPWorkspace.self.declarationLinkSupport = (bool)args.capabilities.textDocument.declaration.linkSupport;
                    }

                    capabilities.declarationProvider = false; //textDocument/declaration
                }

                if (args.capabilities.textDocument.definition != null)
                {
                    if (args.capabilities.textDocument.definition.linkSupport != null)
                    {
                        BHLSPWorkspace.self.definitionLinkSupport = (bool)args.capabilities.textDocument.definition.linkSupport;
                    }

                    capabilities.definitionProvider = true; //textDocument/definition
                }

                if (args.capabilities.textDocument.typeDefinition != null)
                {
                    if (args.capabilities.textDocument.typeDefinition.linkSupport != null)
                    {
                        BHLSPWorkspace.self.typeDefinitionLinkSupport = (bool)args.capabilities.textDocument.typeDefinition.linkSupport;
                    }

                    capabilities.typeDefinitionProvider = false; //textDocument/typeDefinition
                }

                if (args.capabilities.textDocument.implementation != null)
                {
                    if (args.capabilities.textDocument.implementation.linkSupport != null)
                    {
                        BHLSPWorkspace.self.implementationLinkSupport = (bool)args.capabilities.textDocument.implementation.linkSupport;
                    }

                    capabilities.implementationProvider = false; //textDocument/implementation
                }

                if (args.capabilities.textDocument.hover != null)
                {
                    capabilities.hoverProvider = true; //textDocument/hover
                }

                if (args.capabilities.textDocument.references != null)
                {
                    capabilities.referencesProvider = false; //textDocument/references
                }

                if (args.capabilities.textDocument.semanticTokens != null)
                {
                    capabilities.semanticTokensProvider = new SemanticTokensOptions
                    {
                        full   = true,
                        range  = false,
                        legend = new SemanticTokensLegend
                        {
                            tokenTypes     = BHLSemanticTokens.semanticTokenTypes,
                            tokenModifiers = BHLSemanticTokens.semanticTokenModifiers
                        }
                    };
                }
            }

            return(RpcResult.Success(new InitializeResult
            {
                capabilities = capabilities,
                serverInfo = new InitializeResult.InitializeResultsServerInfo
                {
                    name = "bhlsp",
                    version = "0.1"
                }
            }));
        }
Exemplo n.º 15
0
        public string HandleMessage(string json)
        {
            RequestMessage  req  = null;
            ResponseMessage resp = null;

            try
            {
                req = JsonConvert.DeserializeObject <RequestMessage>(json);
            }
#if BHLSP_DEBUG
            catch (Exception e)
            {
                BHLSPLogger.WriteLine(e);
                BHLSPLogger.WriteLine($"{json}");
#else
            catch
            {
#endif
                resp = new ResponseMessage
                {
                    error = new ResponseError
                    {
                        code    = (int)ErrorCodes.ParseError,
                        message = "Parse error"
                    }
                };
            }

#if BHLSP_DEBUG
            if (req != null)
            {
                BHLSPLogger.WriteLine($":: bhlsp <-- {req.method}({req.id.Value})");
                //BHLSPLogger.WriteLine($":: bhlsp <-- {json}");
            }
            else
            {
                //BHLSPLogger.WriteLine($":: bhlsp <-- {json}");
            }
#endif

            if (resp == null && req != null)
            {
                if (req.IsMessage())
                {
                    resp = HandleMessage(req);
                }
                else
                {
                    resp = new ResponseMessage
                    {
                        error = new ResponseError
                        {
                            code    = (int)ErrorCodes.InvalidRequest,
                            message = ""
                        }
                    }
                };
            }

            string response = string.Empty;

            if (resp != null)
            {
                /* *
                 * A processed notification message must not send a response back.
                 * They work like events.
                 */
                bool isNotification = req != null && req.id.Value == null;
                if (!isNotification)
                {
                    response = JsonConvert.SerializeObject(resp, Newtonsoft.Json.Formatting.None,
                                                           new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    });

#if BHLSP_DEBUG
                    if (req != null)
                    {
                        BHLSPLogger.WriteLine($":: bhlsp --> {req.method}({req.id.Value})");
                        //BHLSPLogger.WriteLine($":: bhlsp --> {response}");
                    }
                    else
                    {
                        //BHLSPLogger.WriteLine($":: bhlsp --> {response}");
                    }
#endif
                }
            }

            return(response);
        }

        ResponseMessage HandleMessage(RequestMessage request)
        {
            ResponseMessage response;

            try
            {
                if (!string.IsNullOrEmpty(request.method))
                {
                    RpcResult result = CallRpcMethod(request.method, request.@params);

                    response = new ResponseMessage
                    {
                        id     = request.id,
                        result = result.result,
                        error  = result.error
                    };
                }
                else
                {
                    response = new ResponseMessage
                    {
                        id = request.id, error = new ResponseError
                        {
                            code    = (int)ErrorCodes.InvalidRequest,
                            message = ""
                        }
                    };
                }
            }
#if BHLSP_DEBUG
            catch (Exception e)
            {
                BHLSPLogger.WriteLine(e);
#else
            catch
            {
#endif
                response = new ResponseMessage
                {
                    id = request.id, error = new ResponseError
                    {
                        code    = (int)ErrorCodes.InternalError,
                        message = ""
                    }
                };
            }

            return(response);
        }