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; }
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; }