private void GetRuleSettings(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Ow_ruleContext ruleContext)
        {
            DeltinScriptParser.ExprContext eventContext  = null;
            DeltinScriptParser.ExprContext teamContext   = null;
            DeltinScriptParser.ExprContext playerContext = null;

            foreach (var exprContext in ruleContext.expr())
            {
                missingBlockRange = DocRange.GetRange(exprContext);

                EnumValuePair enumSetting = (ExpressionTree.ResultingExpression(parseInfo.GetExpression(scope, exprContext)) as CallVariableAction)?.Calling as EnumValuePair;
                EnumData      enumData    = enumSetting?.Member.Enum;

                if (enumData == null || !ValidRuleEnums.Contains(enumData))
                {
                    parseInfo.Script.Diagnostics.Error("Expected enum of type " + string.Join(", ", ValidRuleEnums.Select(vre => vre.CodeName)) + ".", DocRange.GetRange(exprContext));
                }
                else
                {
                    var alreadySet = new Diagnostic("The " + enumData.CodeName + " rule setting was already set.", DocRange.GetRange(exprContext), Diagnostic.Error);

                    // Get the Event option.
                    if (enumData == EnumData.GetEnum <RuleEvent>())
                    {
                        if (_setEventType)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        EventType     = (RuleEvent)enumSetting.Member.Value;
                        _setEventType = true;
                        eventContext  = exprContext;
                    }
                    // Get the Team option.
                    if (enumData == EnumData.GetEnum <Team>())
                    {
                        if (_setTeam)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        Team        = (Team)enumSetting.Member.Value;
                        _setTeam    = true;
                        teamContext = exprContext;
                    }
                    // Get the Player option.
                    if (enumData == EnumData.GetEnum <PlayerSelector>())
                    {
                        if (_setPlayer)
                        {
                            parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet);
                        }
                        Player        = (PlayerSelector)enumSetting.Member.Value;
                        _setPlayer    = true;
                        playerContext = exprContext;
                    }
                }
            }

            // Syntax error if changing the Team type when the Event type is set to Global.
            if (_setEventType && EventType == RuleEvent.OngoingGlobal)
            {
                if (Team != Team.All)
                {
                    parseInfo.Script.Diagnostics.Error("Can't change rule Team type with an event type of Ongoing Global.", DocRange.GetRange(teamContext));
                }
                if (Player != PlayerSelector.All)
                {
                    parseInfo.Script.Diagnostics.Error("Can't change rule Player type with an event type of Ongoing Global.", DocRange.GetRange(playerContext));
                }
            }
        }
        public VariableResolve(VariableResolveOptions options, IExpression expression, DocRange expressionRange, FileDiagnostics diagnostics)
        {
            // The expression is a variable.
            if (expression is CallVariableAction)
            {
                // Get the variable being set and the range.
                SetVariable   = (CallVariableAction)expression;
                VariableRange = expressionRange;
            }
            // The expression is an expression tree.
            else if (expression is ExpressionTree tree)
            {
                Tree = tree;
                if (tree.Completed)
                {
                    // If the resulting expression in the tree is not a variable.
                    if (tree.Result is CallVariableAction == false)
                    {
                        NotAVariableRange = tree.ExprContextTree.Last().GetRange();
                    }
                    else
                    {
                        // Get the variable and the range.
                        SetVariable   = (CallVariableAction)tree.Result;
                        VariableRange = tree.ExprContextTree.Last().GetRange();
                    }
                }
            }
            // The expression is not a variable.
            else if (expression != null)
            {
                NotAVariableRange = expressionRange;
            }

            // NotAVariableRange will not be null if the resulting expression is a variable.
            if (NotAVariableRange != null)
            {
                diagnostics.Error("Expected a variable.", NotAVariableRange);
            }

            // Make sure the variable can be set to.
            if (SetVariable != null)
            {
                // Check if the variable is settable.
                if (options.ShouldBeSettable && !SetVariable.Calling.Settable())
                {
                    diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be set to.", VariableRange);
                }

                // Check if the variable is a whole workshop variable.
                if (options.FullVariable)
                {
                    Var asVar = SetVariable.Calling as Var;
                    if (asVar == null || asVar.StoreType != StoreType.FullVariable)
                    {
                        diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed.", VariableRange);
                    }
                }

                // Check for indexers.
                if (!options.CanBeIndexed && SetVariable.Index.Length != 0)
                {
                    diagnostics.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed.", VariableRange);
                }
            }

            DoesResolveToVariable = SetVariable != null;
        }
Example #3
0
        public VariableResolve(ParseInfo parseInfo, VariableResolveOptions options, IExpression expression, DocRange expressionRange, IVariableResolveErrorHandler errorHandler)
        {
            bool treeSettable = true;

            // The expression is a variable.
            if (expression is CallVariableAction)
            {
                // Get the variable being set and the range.
                SetVariable   = (CallVariableAction)expression;
                VariableRange = expressionRange;
            }
            // The expression is an expression tree.
            else if (expression is ExpressionTree tree)
            {
                Tree = tree;
                if (tree.Completed)
                {
                    // If the resulting expression in the tree is not a variable.
                    if (tree.Result is CallVariableAction == false)
                    {
                        NotAVariableRange = tree.ExprContextTree.Last().GetRange();
                    }
                    else
                    {
                        // Get the variable and the range.
                        SetVariable   = (CallVariableAction)tree.Result;
                        VariableRange = tree.ExprContextTree.Last().GetRange();
                        treeSettable  = tree.TargetCanBeSet();
                    }
                }
            }
            // The expression is not a variable.
            else if (expression != null)
            {
                NotAVariableRange = expressionRange;
            }

            // NotAVariableRange will not be null if the resulting expression is a variable.
            if (NotAVariableRange != null)
            {
                errorHandler.Error("Expected a variable.", NotAVariableRange);
            }

            // Make sure the variable can be set to.
            if (SetVariable != null)
            {
                // Check if the variable is settable.
                if (options.ShouldBeSettable)
                {
                    // The variable can never be set.
                    if (!SetVariable.Calling.Attributes.CanBeSet)
                    {
                        errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be set", VariableRange);
                    }

                    // The variable is normally settable, but not in the current context.
                    else if (!treeSettable || (parseInfo.ContextualVariableModifiers != null && !parseInfo.ContextualVariableModifiers.IsSettable(SetVariable.Calling)))
                    {
                        errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be set in the current context", VariableRange);
                    }
                }

                // Check if the variable is a whole workshop variable.
                else if ((options.FullVariable && SetVariable.Calling.Attributes.StoreType != StoreType.FullVariable) || (!options.CanBeIndexed && SetVariable.Index.Length != 0))
                {
                    errorHandler.Error($"The variable '{SetVariable.Calling.Name}' cannot be indexed", VariableRange);
                }
            }

            DoesResolveToVariable = SetVariable != null;
        }