Esempio n. 1
0
        public static List <LintIssue> CheckNode(Hinge h, State node)
        {
            List <LintIssue> issues = new List <LintIssue>();

            CheckNullOps(h, h.GetTransitions().Concat(h.GetTriggers()), issues);

            if (node is Transition && !(node as Transition).IsTrigger)
            {
                CheckSymlinks(new Transition[] { node as Transition }, issues);
            }

            if (node is Transition)
            {
                CheckImagesOps(new Transition[] { node as Transition }, issues);
            }

            if (node is Transition)
            {
                CheckVars(h, new Transition[] { node as Transition }, issues, h.InteropNames);
            }

            if (node is Transition)
            {
                CheckStates(h.GetStates(), new Transition[] { node as Transition }, issues);
            }

            return(issues);
        }
Esempio n. 2
0
        public static List <LintIssue> Check(Hinge h)
        {
            // warn: symlink never been used
            // warn: symlink reassigned
            // warn: var assigned but never been used
            // warn: invoke transition arguments misscount
            // warn: invoke transition argument missing

            // warn: substate not found

            // err: state not found
            // err: local var used before assignment
            List <LintIssue> issues = new List <LintIssue>();

            CheckNullOps(h, h.GetTransitions().Concat(h.GetTriggers()), issues);
            CheckSymlinks(h.GetTransitions(), issues);
            CheckImagesOps(h.GetTransitions().Concat(h.GetTriggers()), issues);
            CheckVars(h, h.GetTransitions().Concat(h.GetTriggers()), issues, h.InteropNames);
            CheckStates(h.GetStates(), h.GetTransitions().Concat(h.GetTriggers()), issues);

            return(issues);
        }
Esempio n. 3
0
 private static void CheckNullOps(Hinge h, IEnumerable <Transition> transitionsAndTriggers, List <LintIssue> issues)
 {
     foreach (var t in transitionsAndTriggers)
     {
         foreach (var sect in t.sections)
         {
             foreach (var ex in sect.Body)
             {
                 if (ex.AssignResultVar != null && (ex.AssignResultVar.TypeOfReference == ExpressionValue.RefType.Null ||
                                                    ex.ExLeftPart.TypeOfReference == ExpressionValue.RefType.Null ||
                                                    ex.ExRightPart.TypeOfReference == ExpressionValue.RefType.Null))
                 {
                     issues.Add(new LintIssue {
                         IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = "null ref not allowed in this assign operation"
                     });
                 }
                 else
                 if (ex.ExLeftPart != null && ex.FuncType == ExpressionExecutive.ExecuteType.Assign &&
                     ex.ExLeftPart.TypeOfReference == ExpressionValue.RefType.Null &&
                     ex.ExRightPart != null && ex.ExRightPart.TypeOfReference != ExpressionValue.RefType.Null)
                 {
                     issues.Add(new LintIssue {
                         IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = "null ref not allowed for non image assign"
                     });
                 }
                 else
                 if (ex.ExLeftPart != null && ex.FuncType != ExpressionExecutive.ExecuteType.Assign &&
                     ex.ExLeftPart.TypeOfReference == ExpressionValue.RefType.Null)
                 {
                     issues.Add(new LintIssue {
                         IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = "null ref not allowed in this op"
                     });
                 }
             }
         }
     }
 }
Esempio n. 4
0
        private static void CheckVars(Hinge h, IEnumerable <Transition> transitionsAndTriggers, List <LintIssue> issues, SortedSet <string> invocationNames)
        {
            foreach (var t in transitionsAndTriggers)
            {
                Dictionary <string, bool> usings = new Dictionary <string, bool>();
                if (!t.IsTrigger)
                {
                    foreach (var s in t.symlinks)
                    {
                        usings.Add(s.Value.VarName, false);
                    }
                }
                SortedSet <string> assignedVars = new SortedSet <string>();
                foreach (var sect in t.sections)
                {
                    bool  listDefined = false;
                    State toListNode  = null;
                    foreach (var ex in sect.Body)
                    {
                        if (ex.FuncType == ExpressionExecutive.ExecuteType.Invocation &&
                            ((!h.AllNodesDict.ContainsKey(ex.InvokeTransitionName)) ||
                             (!(h.AllNodesDict[ex.InvokeTransitionName] is Transition) && (!(h.AllNodesDict[ex.InvokeTransitionName] is Dialogue))) ||
                             (h.AllNodesDict[ex.InvokeTransitionName] is Transition) && (h.AllNodesDict[ex.InvokeTransitionName] as Transition).IsTrigger))
                        {
                            if (ex.InvokeTransitionName == "say" && !(t is Dialogue))
                            {
                                issues.Add(new LintIssue {
                                    IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"say proc allowed only in dialogues "
                                });
                            }
                            else
                            if (!invocationNames.Contains(ex.InvokeTransitionName))
                            {
                                issues.Add(new LintIssue {
                                    IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"Invocation \"{ex.InvokeTransitionName}\" not found, or not transition or dialogue "
                                });
                            }
                        }
                        if (ex.FuncType == ExpressionExecutive.ExecuteType.ToList)
                        {
                            if (!h.AllNodesDict.ContainsKey(ex.InvokeArgs[0].Left))
                            {
                                issues.Add(new LintIssue {
                                    IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"State node \"{ex.InvokeArgs[0].Left}\" not found, toList op "
                                });
                            }
                            else
                            {
                                toListNode  = h.AllNodesDict[ex.InvokeArgs[0].Left];
                                listDefined = true;
                            }
                        }
                        if ((ex.ExLeftPart != null && ex.ExLeftPart.TypeOfReference == ExpressionValue.RefType.List) ||
                            (ex.ExRightPart != null && ex.ExRightPart.TypeOfReference == ExpressionValue.RefType.List))
                        {
                            if (!listDefined)
                            {
                                issues.Add(new LintIssue {
                                    IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"list reference used before assignment"
                                });
                            }
                            else
                            {
                                if (ex.ExLeftPart != null && ex.ExLeftPart.TypeOfReference == ExpressionValue.RefType.List &&
                                    (toListNode.Substates.Count <= ex.ExLeftPart.ArgOrListIndex || ex.ExLeftPart.ArgOrListIndex < 0))
                                {
                                    issues.Add(new LintIssue {
                                        IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"list reference {ex.ExLeftPart.ArgOrListIndex} out of substate list bounds"
                                    });
                                }
                                if (ex.ExRightPart != null && ex.ExRightPart.TypeOfReference == ExpressionValue.RefType.List &&
                                    (toListNode.Substates.Count <= ex.ExRightPart.ArgOrListIndex || ex.ExRightPart.ArgOrListIndex < 0))
                                {
                                    issues.Add(new LintIssue {
                                        IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = $"list reference {ex.ExRightPart.ArgOrListIndex} out of substate list bounds"
                                    });
                                }
                            }
                        }

                        foreach (var varname in ex.GetVarsReaded())
                        {
                            if (!assignedVars.Contains(varname) && !usings.ContainsKey(varname) && varname != "image")
                            {
                                issues.Add(new LintIssue {
                                    IssueType = LintIssueType.error, LineNumber = ex.LineNumber, Message = "variable " + varname + " used before assignment"
                                });
                            }
                        }
                        foreach (var varas in ex.GetVarsAssigned())
                        {
                            assignedVars.Add(varas);
                        }
                    }
                }
            }
        }