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