예제 #1
0
파일: document.cs 프로젝트: bitdotgames/bhl
        private void AddSemanticToken(int startIdx, int stopIdx, string tokenType, params string[] tokenModifiers)
        {
            if (startIdx < 0 || stopIdx < 0)
            {
                return;
            }

            if (string.IsNullOrEmpty(tokenType))
            {
                return;
            }

            var t = Array.IndexOf(BHLSemanticTokens.semanticTokenTypes, tokenType);

            if (t < 0)
            {
                return;
            }

            var nextStart        = document.GetLineColumn(next);
            var lineColumnSymbol = document.GetLineColumn(startIdx);

            var diffLine   = lineColumnSymbol.Item1 - nextStart.Item1;
            var diffColumn = diffLine != 0 ? lineColumnSymbol.Item2 : lineColumnSymbol.Item2 - nextStart.Item2;

            int bitTokenModifiers = 0;

            for (int i = 0; i < tokenModifiers.Length; i++)
            {
                var idx = Array.IndexOf(BHLSemanticTokens.semanticTokenModifiers, tokenModifiers[i]);
                bitTokenModifiers |= (int)Math.Pow(2, idx);
            }

            // line
            dataSemanticTokens.Add((uint)diffLine);
            // startChar
            dataSemanticTokens.Add((uint)diffColumn);
            // length
            dataSemanticTokens.Add((uint)(stopIdx - startIdx + 1));
            // tokenType
            dataSemanticTokens.Add((uint)t);
            // tokenModifiers
            dataSemanticTokens.Add((uint)bitTokenModifiers);

            next = startIdx;
        }
예제 #2
0
파일: services.cs 프로젝트: bitdotgames/bhl
        /**
         * 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());
        }