public SetVariableAction(ParseInfo parseInfo, Scope scope, Assignment assignmentContext)
        {
            // Get the variable expression.
            IExpression variableExpression = parseInfo.GetExpression(scope, assignmentContext.VariableExpression);

            // Extract the variable data.
            _variableResolve = new VariableResolve(parseInfo, new VariableResolveOptions()
            {
                ShouldBeSettable = true
            }, variableExpression, assignmentContext.VariableExpression.Range);

            // Get the value.
            _value = parseInfo.SetExpectType(_variableResolve.SetVariable?.Type()).GetExpression(scope, assignmentContext.Value);

            // Get the operation.
            Token              assignmentToken = assignmentContext.AssignmentToken;
            CodeType           variableType = variableExpression.Type(), valueType = _value.Type();
            AssignmentOperator op = AssignmentOperation.OperatorFromTokenType(assignmentToken.TokenType);

            _operation = variableType.Operations.GetOperation(op, valueType);

            // No operators exist for the variable and value pair.
            if (_operation == null)
            {
                // If the variable type is any, use default operation.
                if (assignmentToken.TokenType == TokenType.Equal && variableType.Operations.DefaultAssignment && TypeComparison.IsAny(parseInfo.Types, variableType))
                {
                    _operation = new AssignmentOperation(op, parseInfo.Types.Any());
                }
                // Otherwise, add an error.
                else
                {
                    parseInfo.Script.Diagnostics.Error("Operator '" + assignmentToken.Text + "' cannot be applied to the types '" + variableType.GetNameOrAny() + "' and '" + valueType.GetNameOrAny() + "'.", assignmentToken.Range);
                }
            }
        }
        public static void GetHook(ParseInfo parseInfo, Scope scope, Hook context)
        {
            parseInfo = parseInfo.SetCallInfo(new CallInfo(parseInfo.Script));

            // Get the hook variable's expression.
            IExpression variableExpression = parseInfo.GetExpression(scope, context.Variable);

            // Resolve the variable.
            VariableResolve resolvedVariable = new VariableResolve(parseInfo, new VariableResolveOptions()
            {
                // Not indexable
                CanBeIndexed = false,
                // Hook variables are not settable.
                ShouldBeSettable = false
            }, variableExpression, context.Variable.Range);

            // Check if the resolved variable is a HookVar.
            if (resolvedVariable.SetVariable?.Calling is HookVar hookVar)
            {
                // Get the hook value.
                IExpression valueExpression = parseInfo.SetExpectType(hookVar.CodeType.GetCodeType(parseInfo.TranslateInfo)).GetExpression(scope, context.Value);

                if (valueExpression == null)
                {
                    return;
                }

                // If it is, set the hook.
                hookVar.TrySet(parseInfo, valueExpression, context.Value.Range);
            }
            else
            {
                // Not a hook variable.
                parseInfo.Script.Diagnostics.Error("Expected a hook variable.", context.Variable.Range);
            }
        }
        private void GetInitialValue()
        {
            // Get the initial value.
            if (_initialValueContext != null)
            {
                ParseInfo parseInfo = this._parseInfo;

                // Store the initial value's restricted calls.
                RestrictedCallList restrictedCalls = null;
                if (_handleRestrictedCalls)
                {
                    restrictedCalls = new RestrictedCallList();
                    parseInfo       = parseInfo.SetRestrictedCallHandler(restrictedCalls);
                }

                ParseInfo initialValueParseInfo = parseInfo.SetExpectType(CodeType);
                if (parseInfo.CurrentCallInfo == null)
                {
                    CallInfo callInfo = new CallInfo(parseInfo.Script);
                    initialValueParseInfo = initialValueParseInfo.SetCallInfo(callInfo);
                }

                // Parse the initial value.
                InitialValue = initialValueParseInfo.GetExpression(_operationalScope, _initialValueContext);

                // Get the inferred type.
                if (_inferType)
                {
                    CodeType = InitialValue.Type();
                    _variableTypeHandler.SetType(CodeType);
                    AddScriptData();
                }

                // If the initial value's type is constant, make sure the constant type's implements the variable's type.
                if (InitialValue?.Type() != null && InitialValue.Type().IsConstant() && !InitialValue.Type().Implements(CodeType))
                {
                    parseInfo.Script.Diagnostics.Error($"The type '{InitialValue.Type().Name}' cannot be stored.", _initialValueContext.Range);
                }

                // If the variable's type is constant, make sure the value's type matches.
                else
                {
                    SemanticsHelper.ExpectValueType(parseInfo, InitialValue, CodeType, _initialValueContext.Range);
                }

                // Check restricted calls.
                if (_handleRestrictedCalls)
                {
                    foreach (RestrictedCall call in restrictedCalls)
                    {
                        // If the variable type is global, or the variable type is player and the restricted call type is not player...
                        if (VariableType == VariableType.Global ||
                            (VariableType == VariableType.Player && call.CallType != RestrictedCallType.EventPlayer))
                        {
                            // ... then add the error.
                            call.AddDiagnostic(parseInfo.Script.Diagnostics);
                        }
                    }
                }
            }

            ValueReady.Set();
        }