private bool PropagateIRVariableType(IRRule rule, IRVariable variable, ValueType type)
        {
            bool updated = false;
            var  ruleVar = rule.Variables[variable.Index];

            if (ruleVar.Type == null)
            {
                ruleVar.Type = type;
                updated      = true;
            }

            if (variable.Type == null)
            {
                // If a more specific type alias is available from the rule variable, apply the
                // rule type instead of the function argument type
                if (ruleVar.Type.IsAliasOf(type))
                {
                    variable.Type = ruleVar.Type;
                }
                else
                {
                    variable.Type = type;
                }

                updated = true;
            }

            return(updated);
        }
        private void VerifyIRVariable(IRRule rule, IRVariable variable, FunctionSignature func)
        {
            var ruleVar = rule.Variables[variable.Index];

            if (variable.Type == null)
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.UnresolvedType,
                                  "Type of variable {0} could not be determined",
                                  ruleVar.Name);
                return;
            }

            if (ruleVar.Type == null)
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.UnresolvedType,
                                  "Type of rule variable {0} could not be determined",
                                  ruleVar.Name);
                return;
            }

            if ((func == null || TypeCoercionWhitelist == null || !TypeCoercionWhitelist.Contains(func.GetNameAndArity().ToString())) &&
                !AllowTypeCoercion)
            {
                if (!AreIntrinsicTypesCompatible(ruleVar.Type.IntrinsicTypeId, variable.Type.IntrinsicTypeId))
                {
                    Context.Log.Error(variable.Location,
                                      DiagnosticCode.CastToUnrelatedType,
                                      "Cannot cast {1} variable {0} to unrelated type {2}",
                                      ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
                    return;
                }

                if (IsRiskyComparison(ruleVar.Type.IntrinsicTypeId, variable.Type.IntrinsicTypeId))
                {
                    Context.Log.Error(variable.Location,
                                      DiagnosticCode.RiskyComparison,
                                      "Coercion of {1} variable {0} to {2} may trigger incorrect behavior",
                                      ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
                    return;
                }

                if (IsGuidAliasToAliasCast(ruleVar.Type, variable.Type))
                {
                    Context.Log.Error(variable.Location,
                                      DiagnosticCode.CastToUnrelatedGuidAlias,
                                      "{1} variable {0} converted to unrelated type {2}",
                                      ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
                }
            }
        }
Exemple #3
0
        private void VerifyIRVariable(IRRule rule, IRVariable variable)
        {
            var ruleVar = rule.Variables[variable.Index];

            if (variable.Type == null)
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.UnresolvedType,
                                  "Type of variable {0} could not be determined",
                                  ruleVar.Name);
                return;
            }

            if (ruleVar.Type == null)
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.UnresolvedType,
                                  "Type of rule variable {0} could not be determined",
                                  ruleVar.Name);
                return;
            }

            if (!AreIntrinsicTypesCompatible(ruleVar.Type.IntrinsicTypeId, variable.Type.IntrinsicTypeId))
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.CastToUnrelatedType,
                                  "Cannot cast {1} variable {0} to unrelated type {2}",
                                  ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
                return;
            }

            if (IsRiskyComparison(ruleVar.Type.IntrinsicTypeId, variable.Type.IntrinsicTypeId))
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.RiskyComparison,
                                  "Coercion of {1} variable {0} to {2} may trigger incorrect behavior",
                                  ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
                return;
            }

            if (IsGuidAliasToAliasCast(ruleVar.Type, variable.Type))
            {
                Context.Log.Error(variable.Location,
                                  DiagnosticCode.CastToUnrelatedGuidAlias,
                                  "{1} variable {0} converted to unrelated type {2}",
                                  ruleVar.Name, ruleVar.Type.Name, variable.Type.Name);
            }
        }
Exemple #4
0
        private void VerifyIRVariableCall(IRRule rule, IRVariable variable, FunctionSignature signature, Int32 parameterIndex, 
            Int32 conditionIndex, bool not)
        {
            var ruleVar = rule.Variables[variable.Index];
            var param = signature.Params[parameterIndex];

            if (param.Direction == ParamDirection.Out && !not)
            {
                Debug.Assert(conditionIndex != -1);
                if (ruleVar.FirstBindingIndex == -1)
                {
                    ruleVar.FirstBindingIndex = conditionIndex;
                }
            }
            else if (
                // We're in the THEN section of a rule, so we cannot bind here
                conditionIndex == -1 
                // NOT conditions never bind, but they allow unbound unused variables
                || (!ruleVar.IsUnused() && not)
                || (
                    // Databases and events always bind
                    signature.Type != FunctionType.Database
                    && signature.Type != FunctionType.Event
                    // PROC/QRYs bind if they're the first condition in a rule
                    && !(rule.Type == RuleType.Proc && conditionIndex == 0 && signature.Type == FunctionType.Proc)
                    && !(rule.Type == RuleType.Query && conditionIndex == 0 && signature.Type == FunctionType.UserQuery)
                    && param.Direction != ParamDirection.Out
                )
            ) {

                if (
                    // The variable was never bound
                    ruleVar.FirstBindingIndex == -1
                    // The variable was bound after this node (so it is still unbound here)
                    || (conditionIndex != -1 && ruleVar.FirstBindingIndex >= conditionIndex)
                ) {
                    object paramName = (param.Name != null) ? (object)param.Name : (parameterIndex + 1);
                    if (!ruleVar.IsUnused())
                    {
                        Context.Log.Error(variable.Location,
                            DiagnosticCode.ParamNotBound,
                            "Variable {0} is not bound here (when used as parameter {1} of {2} \"{3}\")",
                            ruleVar.Name, paramName, signature.Type, signature.GetNameAndArity());
                    }
                    else
                    {
                        Context.Log.Error(variable.Location,
                            DiagnosticCode.ParamNotBound,
                            "Parameter {0} of {1} \"{2}\" requires a variable or constant, not a placeholder",
                            paramName, signature.Type, signature.GetNameAndArity());
                    }
                }
            }
            else
            {
                if (conditionIndex != -1 && ruleVar.FirstBindingIndex == -1 && !not)
                {
                    ruleVar.FirstBindingIndex = conditionIndex;
                }
            }
        }