Exemplo n.º 1
0
 public frmLoading(UserMethod me)
 {
     InitializeComponent();
     this.method = me;
 }
Exemplo n.º 2
0
        public SkryptObject ExecuteExpression(Node node, ScopeContext scopeContext)
        {
            Operator op = Operator.AllOperators.Find(o => o.OperationName == node.Body || o.Operation == node.Body);

            if (op != null)
            {
                if (op.OperationName == "return")
                {
                    if (!scopeContext.subContext.InMethod)
                    {
                        engine.throwError("Can't use return operator outside method!", node.SubNodes[0].Token);
                    }

                    SkryptObject result = null;

                    if (node.SubNodes.Count == 1)
                    {
                        result = ExecuteExpression(node.SubNodes[0], scopeContext);
                    }
                    else
                    {
                        result = new Library.Native.System.Void();
                    }

                    scopeContext.subContext.ReturnObject = result;
                    return(result);
                }

                if (op.OperationName == "access")
                {
                    SkryptObject Target = ExecuteExpression(node.SubNodes[1], scopeContext);
                    SkryptObject Result = ExecuteAccess(Target, node.SubNodes[0], scopeContext).Value;
                    return(Result);
                }

                if (op.OperationName == "assign")
                {
                    SkryptObject result = ExecuteExpression(node.SubNodes[1], scopeContext);

                    if (node.SubNodes[0].SubNodes.Count == 0 && node.SubNodes[0].TokenType == "Identifier")
                    {
                        Variable Variable = getVariable(node.SubNodes[0].Body, scopeContext);

                        if (Variable != null)
                        {
                            Variable.Value = result;
                        }
                        else
                        {
                            scopeContext.Variables[node.SubNodes[0].Body] = new Variable {
                                Name  = node.SubNodes[0].Body,
                                Value = result,
                                Scope = scopeContext
                            };
                        }
                    }
                    else if (node.SubNodes[0].Body == "access")
                    {
                        SkryptObject   Target       = ExecuteExpression(node.SubNodes[0].SubNodes[1], scopeContext);
                        SkryptProperty AccessResult = ExecuteAccess(Target, node.SubNodes[0].SubNodes[0], scopeContext);

                        AccessResult.Value = result;
                    }
                    else if (node.SubNodes[0].Body == "Index")
                    {
                        ExecuteIndexSet(result, node.SubNodes[0], scopeContext);
                    }
                    else
                    {
                        engine.throwError("Left hand side needs to be a variable or property!", node.SubNodes[0].Token);
                    }

                    return(result);
                }

                if (op.Members == 2)
                {
                    SkryptObject LeftResult  = ExecuteExpression(node.SubNodes[0], scopeContext);
                    SkryptObject RightResult = ExecuteExpression(node.SubNodes[1], scopeContext);

                    dynamic Left  = Convert.ChangeType(LeftResult, LeftResult.GetType());
                    dynamic Right = Convert.ChangeType(RightResult, RightResult.GetType());

                    Operation OpLeft  = Left.GetOperation(op.OperationName, LeftResult.GetType(), RightResult.GetType(), Left.Operations);
                    Operation OpRight = Right.GetOperation(op.OperationName, LeftResult.GetType(), RightResult.GetType(), Right.Operations);

                    OperationDelegate Operation = null;

                    if (OpLeft != null)
                    {
                        Operation = OpLeft.operation;
                    }
                    else if (OpRight != null)
                    {
                        Operation = OpRight.operation;
                    }
                    else
                    {
                        engine.throwError("No such operation as " + Left.Name + " " + op.Operation + " " + Right.Name, node.SubNodes[0].Token);
                    }

                    return(Operation(new SkryptObject[] { LeftResult, RightResult }));
                }
                else if (op.Members == 1)
                {
                    SkryptObject LeftResult = ExecuteExpression(node.SubNodes[0], scopeContext);

                    dynamic Left = Convert.ChangeType(LeftResult, LeftResult.GetType());

                    Operation OpLeft = Left.GetOperation(op.OperationName, LeftResult.GetType(), null, Left.Operations);

                    OperationDelegate Operation = null;

                    if (OpLeft != null)
                    {
                        Operation = OpLeft.operation;
                    }
                    else
                    {
                        engine.throwError("No such operation as " + Left.Name + " " + op.Operation, node.SubNodes[0].Token);
                    }

                    return(Operation(new SkryptObject[] { LeftResult }));
                }
            }
            else if (node.TokenType == "ArrayLiteral")
            {
                Library.Native.System.Array array = new Library.Native.System.Array();

                for (int i = 0; i < node.SubNodes.Count; i++)
                {
                    Node subNode = node.SubNodes[i];

                    SkryptObject Result = ExecuteExpression(subNode, scopeContext);

                    if (Result.Name == "void")
                    {
                        engine.throwError("Can't add void to array!", node.SubNodes[0].Token);
                    }

                    array.value["" + i] = Result;
                }

                return(array);
            }
            else if (node.SubNodes.Count == 0)
            {
                switch (node.TokenType)
                {
                case "NumericLiteral":
                    return(new Library.Native.System.Numeric(Double.Parse(node.Body)));

                case "StringLiteral":
                    return(new Library.Native.System.String(node.Body));

                case "BooleanLiteral":
                    return(new Library.Native.System.Boolean(node.Body == "true" ? true : false));

                case "NullLiteral":
                    return(new Library.Native.System.Null());
                }
            }
            else if (node.TokenType == "FunctionLiteral")
            {
                UserMethod result = new UserMethod();
                result.Name      = "method";
                result.Signature = node.Body;
                result.BlockNode = node.SubNodes[0];
                result.CallName  = node.Body.Split('_')[0];

                foreach (Node snode in node.SubNodes[1].SubNodes)
                {
                    result.Parameters.Add(snode.Body);
                }

                return(result);
            }

            if (node.TokenType == "Identifier")
            {
                if (engine.Constants.ContainsKey(node.Body))
                {
                    return(engine.Constants[node.Body]);
                }

                Variable foundVariable = getVariable(node.Body, scopeContext);

                if (foundVariable != null)
                {
                    return(foundVariable.Value);
                }
                else
                {
                    engine.throwError("Variable '" + node.Body + "' does not exist in the current context!", node.Token);
                }
            }

            if (node.TokenType == "Index")
            {
                return(ExecuteIndex(node, scopeContext));
            }

            if (node.TokenType == "Call")
            {
                List <SkryptObject> Arguments     = new List <SkryptObject>();
                ScopeContext        methodContext = new ScopeContext {
                    ParentScope = scopeContext
                };

                foreach (Node subNode in node.SubNodes[1].SubNodes)
                {
                    SkryptObject Result = ExecuteExpression(subNode, scopeContext);

                    if (Result.Name == "void")
                    {
                        engine.throwError("Can't pass void into arguments!", node.SubNodes[0].Token);
                    }

                    Arguments.Add(Result);
                }

                SkryptObject Method = ExecuteExpression(node.SubNodes[0].SubNodes[0], scopeContext);

                if (Method.GetType() != typeof(SharpMethod))
                {
                    var Find = Method.Properties.Find((x) => x.Name == "Constructor");

                    if (Find != null)
                    {
                        Method = Find.Value;
                    }
                }

                if (Method.GetType() == typeof(UserMethod))
                {
                    UserMethod method = (UserMethod)Method;

                    for (int i = 0; i < method.Parameters.Count; i++)
                    {
                        string       parName = method.Parameters[i];
                        SkryptObject input;

                        if (i < Arguments.Count)
                        {
                            input = Arguments[i];
                        }
                        else
                        {
                            input = new Library.Native.System.Null();
                        }

                        methodContext.Variables[parName] = new Variable {
                            Name  = parName,
                            Value = input,
                            Scope = methodContext
                        };
                    }

                    SkryptObject MethodResult = method.Execute(engine, Arguments.ToArray(), methodContext);

                    return(MethodResult);
                }
                else if (Method.GetType() == typeof(SharpMethod))
                {
                    SkryptObject MethodResult = ((SharpMethod)Method).Execute(engine, Arguments.ToArray(), methodContext);

                    return(MethodResult);
                }
                else
                {
                    engine.throwError("Cannot call value, as it is not a function!", node.SubNodes[0].SubNodes[0].Token);
                }
            }

            return(null);
        }
        string GetAutocomplete(string json)
        {
            /*
             *  Format:
             *      textDocument
             *      caret
             *          caret.line
             *          caret.character
             */
            PosData posData = GetPosData(json);

            if (posData == null)
            {
                return(null);
            }

            List <CompletionItem> completion = new List <CompletionItem>();

            if (posData.SelectedNode != null)
            {
                switch (posData.SelectedNode.FirstOrDefault())
                {
                // Ruleset
                case RulesetNode rulesetNode:

                    completion.AddRange(new CompletionItem[]
                    {
                        new CompletionItem("rule")
                        {
                            kind = CompletionItem.Keyword, textEdit = TextEdit.Insert(posData.Caret, Extras.Lines(
                                                                                          "rule: \"My Rule\"",
                                                                                          "Event.OngoingGlobal",
                                                                                          "{",
                                                                                          "}"
                                                                                          ))
                        },
                        new CompletionItem("define")
                        {
                            kind = CompletionItem.Keyword
                        },
                        new CompletionItem("method")
                        {
                            kind = CompletionItem.Keyword, textEdit = TextEdit.Insert(posData.Caret, Extras.Lines(
                                                                                          "method myMethod()",
                                                                                          "{",
                                                                                          "}"
                                                                                          ))
                        },
                        new CompletionItem("class")
                        {
                            kind = CompletionItem.Keyword
                        },
                        new CompletionItem("struct")
                        {
                            kind = CompletionItem.Keyword
                        }
                    });
                    break;

                // Rule node
                case RuleNode ruleNode:

                    // Event type
                    if (ruleNode.IsEventOptionSelected(posData.Caret))
                    {
                        completion.AddRange(EnumData.GetEnum <RuleEvent>().GetCompletion());
                    }

                    // Player
                    else if (ruleNode.IsPlayerOptionSelected(posData.Caret))
                    {
                        completion.AddRange(EnumData.GetEnum <PlayerSelector>().GetCompletion());
                    }

                    // Team
                    else if (ruleNode.IsTeamOptionSelected(posData.Caret))
                    {
                        completion.AddRange(EnumData.GetEnum <Team>().GetCompletion());
                    }

                    else if (ruleNode.IsIfSelected(posData.Caret))
                    {
                        completion.AddRange(Element.GetCompletion(true, false));
                    }

                    else
                    {
                        completion.AddRange(new CompletionItem[]
                        {
                            new CompletionItem("Event")
                            {
                                kind = CompletionItem.Enum
                            },
                            new CompletionItem("Team")
                            {
                                kind = CompletionItem.Enum
                            },
                            new CompletionItem("Player")
                            {
                                kind = CompletionItem.Enum
                            },
                        });
                    }
                    break;

                // Actions
                case BlockNode blockNode:

                    // Get all action methods
                    completion.AddRange(Element.GetCompletion(true, true));
                    completion.AddRange(CustomMethodData.GetCompletion());

                    if (parserData.Success)
                    {
                        // Get all variables
                        if (blockNode.RelatedScopeGroup != null)
                        {
                            completion.AddRange(blockNode.RelatedScopeGroup.GetCompletionItems(posData.Caret));
                        }
                        // Get custom methods
                        if (parserData.UserMethods != null)
                        {
                            completion.AddRange(UserMethod.CollectionCompletion(parserData.UserMethods.ToArray()));
                        }
                        // Get structs
                        if (parserData.DefinedTypes != null)
                        {
                            completion.AddRange(DefinedType.CollectionCompletion(parserData.DefinedTypes.ToArray()));
                        }
                    }

                    break;

                // Values
                case MethodNode methodNode:

                    completion.AddRange(Element.GetCompletion(true, false));
                    completion.AddRange(EnumData.GetAllEnumCompletion());
                    completion.AddRange(CustomMethodData.GetCompletion());

                    if (parserData.Success)
                    {
                        // Get all variables
                        if (methodNode.RelatedScopeGroup != null)
                        {
                            completion.AddRange(methodNode.RelatedScopeGroup?.GetCompletionItems(posData.Caret));
                        }
                        // Get custom methods
                        if (parserData.UserMethods != null)
                        {
                            completion.AddRange(UserMethod.CollectionCompletion(parserData.UserMethods.ToArray()));
                        }
                    }

                    break;

                // If the selected node is a string node, show all strings.
                case StringNode stringNode:

                    completion.AddRange(Constants.Strings.Select(str =>
                                                                 new CompletionItem(str)
                    {
                        kind = CompletionItem.Text
                    }
                                                                 ));

                    break;

                case EnumNode enumNode:
                    var add = EnumData.GetEnum(enumNode.Type)?.GetCompletion();

                    if (add != null)
                    {
                        completion.AddRange(add);
                    }

                    break;

                case ImportNode importNode:

                    string currentPath = importNode.File;

                    string path = Extras.CombinePathWithDotNotation(posData.File, importNode.File);

                    if (path != null)
                    {
                        completion.Add(new CompletionItem("../")
                        {
                            kind = CompletionItem.Folder
                        });

                        // GetDirectoryName can return null even if path isn't null.
                        path = Path.GetDirectoryName(path);

                        if (path != null)
                        {
                            foreach (string fullDirectoryPath in Directory.GetDirectories(path))
                            {
                                string directory = new DirectoryInfo(fullDirectoryPath).Name;
                                completion.Add(new CompletionItem(directory)
                                {
                                    kind = CompletionItem.Folder
                                });
                            }
                            foreach (string fullFilePath in Directory.GetFiles(path))
                            {
                                string file = Path.GetFileName(fullFilePath);
                                completion.Add(new CompletionItem(file)
                                {
                                    kind = CompletionItem.File
                                });
                            }
                        }
                    }

                    break;
                }
            }

            return(JsonConvert.SerializeObject(completion.ToArray()));
        }
Exemplo n.º 4
0
        private UserMethod DefineMethod(UserType type, String name, List <string> modifiers, String _return, String[] parTypes, String[] parNames)
        {
            bool overrid = modifiers.Remove("override");

            if (overrid)
            {
                modifiers.Add("virtual");
            }
            if (!type.IsAbstract && modifiers.Contains("abstract"))
            {
                throw new CheckerException("Cannot declare abstract method " + name + " in a non-abstract class: " + type.Name);
            }
            if (modifiers.Contains("abstract"))
            {
                modifiers.Add("virtual");
            }
            MethodAttributes attr = MethodAttributes.HideBySig;

            foreach (String s in modifiers)
            {
                attr |= (MethodAttributes)Enum.Parse(typeof(MethodAttributes), s, true);
            }

            IdEntry[] pars = new IdEntry[parTypes.Length];
            for (int i = 0; i < parTypes.Length; i++)
            {
                pars[i] = this.GetTypeIdEntry(parTypes[i]);
            }
            IdEntry ret = KeywordToType(_return) != null ? new IdEntry()
            {
                ReflectionObject = KeywordToType(_return)
            } : this.GetTypeIdEntry(_return);

            if (overrid)
            {
                MethodInfo m = type.BaseType.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null);
                if (m == null || m.ReturnType != ret.ReflectionObject)
                {
                    throw new CheckerException("No suitable method found to override: " + name);
                }
                if (!m.IsVirtual)
                {
                    throw new CheckerException("Cannot override a non-virtual method: " + m.Name);
                }
            }
            else
            {
                MethodInfo m = type.GetMethod(name, BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, LibraryChecker.ToArray <Type>(pars), null);
                if (m != null)
                {
                    throw new CheckerException("Method already exists: " + m.Name);
                }
                if (type.GetInterfaceMethod(name, LibraryChecker.ToArray <Type>(pars)) != null)
                {
                    attr |= MethodAttributes.NewSlot | MethodAttributes.Virtual;
                }
            }
            UserMethod metb = type.DefineMethod(name, attr, ret, pars, parNames);

            return(metb);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Finally walk all members of the classes and interfaces. Methods etc. are defined here
        /// </summary>
        public void WalkClassMembers()
        {
            CheckerException exc     = new CheckerException();
            bool             hasMain = false;

            for (int i = 0; i < reorderedTypes.Count; i++)
            {
                TreeNode n = reorderedTypes[i];
                currentType = (UserType)n.Entry.ReflectionObject;
                searchPath  = (List <string>)((TreeNode)n.Parent.Parent).Entry.ReflectionObject;
                this.searchPath.Add(currentType.Namespace);

                foreach (TreeNode n2 in n.Children)
                {
                    try
                    {
                        if (n2.Type == VnvdTreeWalker.FIELD)
                        {
                            n2.EntryType = EntryType.Variable;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;
                            string ret = n2.GetChild(1).Type == VnvdTreeWalker.FQUALIFIER
                                     ? AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString()
                                     : n2.GetChild(1).Text;
                            UserField field = DefineField(currentType, n2.GetChild(2).Text, AbstractHelper.GetModifiers(n2.GetChild(0)),
                                                          ret);
                            field.Entry            = entry;
                            entry.ReflectionObject = field;
                            n2.Entry = entry;
                        }
                        else if (n2.Type == VnvdTreeWalker.CONSTRUCTOR)
                        {
                            n2.EntryType = EntryType.Constructor;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;

                            String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(2));
                            String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(2));

                            UserConstructor cons = DefineConstructor(currentType, AbstractHelper.GetModifiers(n2.GetChild(0)), parTypes, parNames);
                            cons.Entry             = entry;
                            entry.ReflectionObject = cons;
                            n2.Entry = entry;
                        }
                        else if (n2.Type == VnvdTreeWalker.METHOD)
                        {
                            n2.EntryType = EntryType.Method;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;

                            String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(3));
                            String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(3));

                            string ret = n2.GetChild(1).Type == VnvdTreeWalker.FQUALIFIER
                         ? AbstractHelper.GetFullQualifier(n2.GetChild(1)).ToString()
                         : n2.GetChild(1).Text;

                            UserMethod met = DefineMethod(currentType, n2.GetChild(2).Text, AbstractHelper.GetModifiers(n2.GetChild(0)), ret, parTypes, parNames);
                            if (met.Name.Equals(GeneratorManual.MAINMETHOD))
                            {
                                if (hasMain)
                                {
                                    throw new CheckerException(n2, "Duplicate main method.");
                                }
                                hasMain = true;
                            }
                            met.Entry = entry;
                            entry.ReflectionObject = met;
                            n2.Entry = entry;
                        }
                        else if (n2.Type == VnvdTreeWalker.IMETHOD)
                        {
                            n2.EntryType = EntryType.Method;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;

                            String[] parNames = AbstractHelper.GetParameterNames(n2.GetChild(2));
                            String[] parTypes = AbstractHelper.GetParameterTypes(n2.GetChild(2));

                            string ret = n2.GetChild(0).Type == VnvdTreeWalker.FQUALIFIER
                         ? AbstractHelper.GetFullQualifier(n2.GetChild(0)).ToString()
                         : n2.GetChild(0).Text;

                            UserMethod met = DefineInterfaceMethod(currentType, n2.GetChild(1).Text, ret, parTypes, parNames);
                            met.Entry = entry;
                            entry.ReflectionObject = met;
                            n2.Entry = entry;
                        }
                        else if (n2.Type == VnvdTreeWalker.SCONSTRUCTOR)
                        {
                            n2.EntryType = EntryType.Constructor;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;
                            UserConstructor cons = currentType.DefineTypeInitializer();
                            cons.Entry             = entry;
                            entry.ReflectionObject = cons;
                            n2.Entry = entry;
                        }
                        else if (n2.Type == VnvdTreeWalker.ENUMOPTION)
                        {
                            n2.EntryType = EntryType.Variable;
                            IdEntry entry = new IdEntry();
                            entry.Node = n2;
                            UserField option = ((UserEnum)currentType).DefineOption(n2.GetChild(0).Text);
                            option.Entry           = entry;
                            entry.ReflectionObject = option;
                            n2.Entry = entry;
                        }
                    }
                    catch (CheckerException ex)
                    {
                        exc.AddError(n2, ex.GetLastError().Second);
                    }
                    catch (InvalidOperationException ex)
                    {
                        exc.AddError(n2, ex.Message);
                    }
                    catch (SymbolTableException ex)
                    {
                        exc.AddError(n2, ex.Message);
                    }
                }

                if (currentType.IsClass && currentType.GetConstructors().Length == 0)
                {
                    UserConstructor uc = DefineConstructor(currentType, new List <string>()
                    {
                        "public"
                    }, new string[] {}, new string[] {});
                    uc.Entry = new IdEntry();
                    uc.Entry.ReflectionObject = uc;
                }

                try
                {
                    if (!currentType.IsInterface)
                    {
                        currentType.CheckInterfaces();
                    }
                }
                catch (CheckerException ex)
                {
                    exc.AddError(n, ex.GetLastError().Second);
                }

                this.searchPath.Remove(currentType.Namespace);
            }

            if (exc.ErrorCount > 0)
            {
                throw exc;
            }
        }
        // https://microsoft.github.io/language-server-protocol/specification#textDocument_hover
        static string GetHover(string json)
        {
            dynamic inputJson = JsonConvert.DeserializeObject(json);
            string  document  = inputJson.textDocument;

            int line      = inputJson.caret.line;
            int character = inputJson.caret.character;
            Pos caret     = new Pos(line, character);

            var parser = ParserData.GetParser(document, new Parse.Pos(caret.line, caret.character));

            Hover hover = null;

            if (parser.Success && parser.Bav.SelectedNode.Count > 0)
            {
                switch (parser.Bav.SelectedNode[0])
                {
                case MethodNode methodNode:

                    var type = Translate.GetMethodType(parser.UserMethods, methodNode.Name);

                    if (type == null)
                    {
                        hover = null;
                    }

                    Parameter[] parameters;
                    if (type == Translate.MethodType.Method)
                    {
                        parameters = Element.GetMethod(methodNode.Name).GetCustomAttributes <Parameter>()
                                     .ToArray();
                    }
                    else if (type == Translate.MethodType.CustomMethod)
                    {
                        parameters = CustomMethods.GetCustomMethod(methodNode.Name).GetCustomAttributes <Parameter>()
                                     .ToArray();
                    }
                    else if (type == Translate.MethodType.UserMethod)
                    {
                        parameters = UserMethod.GetUserMethod(parser.UserMethods, methodNode.Name).Parameters;
                    }
                    else
                    {
                        parameters = null;
                    }

                    if (parameters != null)
                    {
                        hover = new Hover(new MarkupContent(MarkupContent.Markdown, methodNode.Name + "(" + Parameter.ParameterGroupToString(parameters) + ")"))
                        {
                            range = methodNode.Range
                        }
                    }
                    ;
                    break;

                default:
                    hover = null;
                    break;
                }
            }

            return(JsonConvert.SerializeObject(hover));
        }
        static string GetAutocomplete(string json)
        {
            /*
             *  Format:
             *      textDocument
             *      caret
             *          caret.line
             *          caret.character
             */
            dynamic inputJson = JsonConvert.DeserializeObject(json);

            string document = inputJson.textDocument;

            int line      = inputJson.caret.line;
            int character = inputJson.caret.character;
            Pos caret     = new Pos(line, character);

            var parser = ParserData.GetParser(document, new Parse.Pos(caret.line, caret.character));

            List <CompletionItem> completion = new List <CompletionItem>();

            switch (parser.Bav?.SelectedNode.FirstOrDefault())
            {
            // Ruleset
            case RulesetNode rulesetNode:

                completion.AddRange(new CompletionItem[]
                {
                    // TODO insert text
                    new CompletionItem("rule")
                    {
                        kind = CompletionItem.Keyword
                    },
                    new CompletionItem("define")
                    {
                        kind = CompletionItem.Keyword
                    },
                    new CompletionItem("method")
                    {
                        kind = CompletionItem.Keyword
                    }
                });
                break;

            // Rule node
            case RuleNode ruleNode:

                // Event type
                if (ruleNode.IsEventOptionSelected())
                {
                    completion.AddRange(EnumData.GetEnum <RuleEvent>().GetCompletion());
                }

                // Player
                else if (ruleNode.IsPlayerOptionSelected())
                {
                    completion.AddRange(EnumData.GetEnum <PlayerSelector>().GetCompletion());
                }

                // Team
                else if (ruleNode.IsTeamOptionSelected())
                {
                    completion.AddRange(EnumData.GetEnum <TeamSelector>().GetCompletion());
                }

                else
                {
                    completion.AddRange(new CompletionItem[]
                    {
                        new CompletionItem("Event")
                        {
                            kind = CompletionItem.Enum
                        },
                        new CompletionItem("Team")
                        {
                            kind = CompletionItem.Enum
                        },
                        new CompletionItem("Player")
                        {
                            kind = CompletionItem.Enum
                        },
                    });
                }
                break;

            // Actions
            case BlockNode blockNode:

                // Get all action methods
                completion.AddRange(Element.ActionList.Select(m =>
                                                              new CompletionItem(m.Name.Substring(2))
                {
                    kind   = CompletionItem.Method,
                    detail = ((Element)Activator.CreateInstance(m)).ToString(),
                }));
                if (parser.Success)
                {
                    // Get all variables
                    if (blockNode.RelatedScopeGroup != null)
                    {
                        completion.AddRange(blockNode.RelatedScopeGroup.GetCompletionItems());
                    }
                    // Get custom methods
                    if (parser.UserMethods != null)
                    {
                        completion.AddRange(UserMethod.CollectionCompletion(parser.UserMethods));
                    }
                }

                break;

            // Values
            case MethodNode methodNode:

                completion.AddRange(Element.ValueList.Select(m =>
                                                             new CompletionItem(m.Name.Substring(2))
                {
                    kind   = CompletionItem.Method,
                    detail = ((Element)Activator.CreateInstance(m)).ToString(),
                }));

                completion.AddRange(EnumData.GetAllEnumCompletion());

                if (parser.Success)
                {
                    // Get all variables
                    if (methodNode.RelatedScopeGroup != null)
                    {
                        completion.AddRange(methodNode.RelatedScopeGroup?.GetCompletionItems());
                    }
                    // Get custom methods
                    if (parser.UserMethods != null)
                    {
                        completion.AddRange(UserMethod.CollectionCompletion(parser.UserMethods));
                    }
                }

                break;

            // If the selected node is a string node, show all strings.
            case StringNode stringNode:

                completion.AddRange(Constants.Strings.Select(str =>
                                                             new CompletionItem(str)
                {
                    kind = CompletionItem.Text
                }
                                                             ));

                break;

            case EnumNode enumNode:
                var add = EnumData.GetEnum(enumNode.Type)?.GetCompletion();

                if (add != null)
                {
                    completion.AddRange(add);
                }

                break;
            }

            return(JsonConvert.SerializeObject(completion.ToArray()));
        }