private ITreeContextPart[] Flatten(ScriptFile script, DeltinScriptParser.E_expr_treeContext exprContext)
        {
            var exprList = new List <ITreeContextPart>();

            Flatten(script, exprContext, exprList);
            return(exprList.ToArray());

            // Recursive flatten function.
            void Flatten(ScriptFile script, DeltinScriptParser.E_expr_treeContext exprContext, List <ITreeContextPart> exprList)
            {
                // If the expression is a Tree, recursively flatten.
                if (exprContext.expr() is DeltinScriptParser.E_expr_treeContext)
                {
                    Flatten(script, (DeltinScriptParser.E_expr_treeContext)exprContext.expr(), exprList);
                }
                // Otherwise, add the expression to the list.
                else
                {
                    // Get the function.
                    if (exprContext.expr() is DeltinScriptParser.E_methodContext method)
                    {
                        exprList.Add(new FunctionPart(method.method()));
                    }
                    // Get the variable.
                    else if (exprContext.expr() is DeltinScriptParser.E_variableContext variable)
                    {
                        exprList.Add(new VariableOrTypePart(variable.variable()));
                    }
                    // Get the expression.
                    else
                    {
                        exprList.Add(new ExpressionPart(exprContext.expr()));
                    }
                }

                // Syntax error if there is no method or variable.
                if (exprContext.method() == null && exprContext.variable() == null)
                {
                    script.Diagnostics.Error("Expected expression.", DocRange.GetRange(exprContext.SEPERATOR()));
                    _trailingSeperator = exprContext.SEPERATOR();
                }
                else
                {
                    // Get the method.
                    if (exprContext.method() != null)
                    {
                        exprList.Add(new FunctionPart(exprContext.method()));
                    }
                    // Get the variable.
                    if (exprContext.variable() != null)
                    {
                        exprList.Add(new VariableOrTypePart(exprContext.variable()));
                    }
                }
            }
        }
        public ExpressionTree(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_expr_treeContext exprContext, bool usedAsValue)
        {
            ExprContextTree = Flatten(parseInfo.Script, exprContext);

            // Setup
            for (int i = 0; i < ExprContextTree.Length; i++)
            {
                ExprContextTree[i].Setup(new TreeContextParseInfo()
                {
                    ParseInfo        = i == 0 ? parseInfo : parseInfo.SetSourceExpression(ExprContextTree[i - 1]),
                    Getter           = scope,
                    Scope            = i == 0 ? scope : ExprContextTree[i - 1].GetScope() ?? new Scope(),
                    Parent           = i == 0 ? null : ExprContextTree[i - 1],
                    UsedAsExpression = usedAsValue || i < ExprContextTree.Length - 1,
                    IsLast           = i == ExprContextTree.Length - 1
                });
            }

            // Get expressions
            Tree = new IExpression[ExprContextTree.Length];
            IExpression current = ExprContextTree[0].GetExpression();

            Tree[0] = current;
            if (current != null)
            {
                for (int i = 1; i < ExprContextTree.Length; i++)
                {
                    current = ExprContextTree[i].GetExpression();

                    Tree[i] = current;

                    if (current == null)
                    {
                        Completed = false;
                        break;
                    }
                }
            }
            else
            {
                Completed = false;
            }

            if (Completed)
            {
                Result = Tree[Tree.Length - 1];
            }

            // Get the completion items for each expression in the path.
            GetCompletion(parseInfo.Script, scope);
        }
        private TreeContextPart[] Flatten(ScriptFile script, DeltinScriptParser.E_expr_treeContext exprContext)
        {
            var exprList = new List <TreeContextPart>();

            Flatten(script, exprContext, exprList);
            return(exprList.ToArray());

            void Flatten(ScriptFile script, DeltinScriptParser.E_expr_treeContext exprContext, List <TreeContextPart> exprList)
            {
                if (exprContext.expr() is DeltinScriptParser.E_expr_treeContext)
                {
                    Flatten(script, (DeltinScriptParser.E_expr_treeContext)exprContext.expr(), exprList);
                }
                else
                {
                    exprList.Add(new TreeContextPart(exprContext.expr()));
                }

                if (exprContext.method() == null && exprContext.variable() == null)
                {
                    script.Diagnostics.Error("Expected expression.", DocRange.GetRange(exprContext.SEPERATOR()));
                    _trailingSeperator = exprContext.SEPERATOR();
                }
                else
                {
                    if (exprContext.method() != null)
                    {
                        exprList.Add(new TreeContextPart(exprContext.method()));
                    }
                    if (exprContext.variable() != null)
                    {
                        exprList.Add(new TreeContextPart(exprContext.variable()));
                    }
                }
            }
        }
        public ExpressionTree(ParseInfo parseInfo, Scope scope, DeltinScriptParser.E_expr_treeContext exprContext, bool usedAsValue)
        {
            ExprContextTree = Flatten(parseInfo.Script, exprContext);

            Tree = new IExpression[ExprContextTree.Length];
            IExpression current = ExprContextTree[0].Parse(parseInfo, scope, scope, true);

            Tree[0] = current;
            if (current != null)
            {
                for (int i = 1; i < ExprContextTree.Length; i++)
                {
                    current = ExprContextTree[i].Parse(parseInfo, current.ReturningScope() ?? new Scope(), scope, i < ExprContextTree.Length - 1 || usedAsValue);

                    Tree[i] = current;

                    if (current == null)
                    {
                        Completed = false;
                        break;
                    }
                }
            }
            else
            {
                Completed = false;
            }

            if (Completed)
            {
                Result = Tree[Tree.Length - 1];
            }

            // Get the completion items for each expression in the path.
            GetCompletion(parseInfo.Script, scope);
        }