예제 #1
0
        private static RuleDependencyChecker.RuleRelations ExtractRuleRelations(Type recognizer)
        {
            string serializedATN = GetSerializedATN(recognizer);

            if (serializedATN == null)
            {
                return(null);
            }
            ATN atn = new ATNDeserializer().Deserialize(serializedATN.ToCharArray());

            RuleDependencyChecker.RuleRelations relations = new RuleDependencyChecker.RuleRelations(atn.ruleToStartState.Length);
            foreach (ATNState state in atn.states)
            {
                if (!state.epsilonOnlyTransitions)
                {
                    continue;
                }
                foreach (Transition transition in state.GetTransitions())
                {
                    if (transition.TransitionType != TransitionType.Rule)
                    {
                        continue;
                    }
                    RuleTransition ruleTransition = (RuleTransition)transition;
                    relations.AddRuleInvocation(state.ruleIndex, ruleTransition.target.ruleIndex);
                }
            }
            return(relations);
        }
예제 #2
0
        private static void CheckDependencies(IList <Tuple <RuleDependencyAttribute, ICustomAttributeProvider> > dependencies, Type recognizerType)
        {
            string[] ruleNames    = GetRuleNames(recognizerType);
            int[]    ruleVersions = GetRuleVersions(recognizerType, ruleNames);
            RuleDependencyChecker.RuleRelations relations = ExtractRuleRelations(recognizerType);
            StringBuilder errors = new StringBuilder();

            foreach (Tuple <RuleDependencyAttribute, ICustomAttributeProvider> dependency in dependencies)
            {
                if (!dependency.Item1.Recognizer.IsAssignableFrom(recognizerType))
                {
                    continue;
                }
                // this is the rule in the dependency set with the highest version number
                int effectiveRule = dependency.Item1.Rule;
                if (effectiveRule < 0 || effectiveRule >= ruleVersions.Length)
                {
                    string message = string.Format("Rule dependency on unknown rule {0}@{1} in {2}", dependency.Item1.Rule, dependency.Item1.Version, dependency.Item1.Recognizer.ToString());
                    errors.AppendLine(dependency.Item2.ToString());
                    errors.AppendLine(message);
                    continue;
                }
                Dependents dependents = Dependents.Self | dependency.Item1.Dependents;
                ReportUnimplementedDependents(errors, dependency, dependents);
                BitSet @checked = new BitSet();
                int    highestRequiredDependency = CheckDependencyVersion(errors, dependency, ruleNames, ruleVersions, effectiveRule, null);
                if ((dependents & Dependents.Parents) != 0)
                {
                    BitSet parents = relations.parents[dependency.Item1.Rule];
                    for (int parent = parents.NextSetBit(0); parent >= 0; parent = parents.NextSetBit(parent + 1))
                    {
                        if (parent < 0 || parent >= ruleVersions.Length || @checked.Get(parent))
                        {
                            continue;
                        }
                        @checked.Set(parent);
                        int required = CheckDependencyVersion(errors, dependency, ruleNames, ruleVersions, parent, "parent");
                        highestRequiredDependency = Math.Max(highestRequiredDependency, required);
                    }
                }
                if ((dependents & Dependents.Children) != 0)
                {
                    BitSet children = relations.children[dependency.Item1.Rule];
                    for (int child = children.NextSetBit(0); child >= 0; child = children.NextSetBit(child + 1))
                    {
                        if (child < 0 || child >= ruleVersions.Length || @checked.Get(child))
                        {
                            continue;
                        }
                        @checked.Set(child);
                        int required = CheckDependencyVersion(errors, dependency, ruleNames, ruleVersions, child, "child");
                        highestRequiredDependency = Math.Max(highestRequiredDependency, required);
                    }
                }
                if ((dependents & Dependents.Ancestors) != 0)
                {
                    BitSet ancestors = relations.GetAncestors(dependency.Item1.Rule);
                    for (int ancestor = ancestors.NextSetBit(0); ancestor >= 0; ancestor = ancestors.NextSetBit(ancestor + 1))
                    {
                        if (ancestor < 0 || ancestor >= ruleVersions.Length || @checked.Get(ancestor))
                        {
                            continue;
                        }
                        @checked.Set(ancestor);
                        int required = CheckDependencyVersion(errors, dependency, ruleNames, ruleVersions, ancestor, "ancestor");
                        highestRequiredDependency = Math.Max(highestRequiredDependency, required);
                    }
                }
                if ((dependents & Dependents.Descendants) != 0)
                {
                    BitSet descendants = relations.GetDescendants(dependency.Item1.Rule);
                    for (int descendant = descendants.NextSetBit(0); descendant >= 0; descendant = descendants.NextSetBit(descendant + 1))
                    {
                        if (descendant < 0 || descendant >= ruleVersions.Length || @checked.Get(descendant))
                        {
                            continue;
                        }
                        @checked.Set(descendant);
                        int required = CheckDependencyVersion(errors, dependency, ruleNames, ruleVersions, descendant, "descendant");
                        highestRequiredDependency = Math.Max(highestRequiredDependency, required);
                    }
                }
                int declaredVersion = dependency.Item1.Version;
                if (declaredVersion > highestRequiredDependency)
                {
                    string message = string.Format("Rule dependency version mismatch: {0} has maximum dependency version {1} (expected {2}) in {3}", ruleNames[dependency.Item1.Rule], highestRequiredDependency, declaredVersion, dependency.Item1.Recognizer.ToString());
                    errors.AppendLine(dependency.Item2.ToString());
                    errors.AppendLine(message);
                }
            }
            if (errors.Length > 0)
            {
                throw new InvalidOperationException(errors.ToString());
            }
        }
예제 #3
0
 private static RuleDependencyChecker.RuleRelations ExtractRuleRelations(Type recognizer)
 {
     string serializedATN = GetSerializedATN(recognizer);
     if (serializedATN == null)
     {
         return null;
     }
     ATN atn = new ATNDeserializer().Deserialize(serializedATN.ToCharArray());
     RuleDependencyChecker.RuleRelations relations = new RuleDependencyChecker.RuleRelations(atn.ruleToStartState.Length);
     foreach (ATNState state in atn.states)
     {
         if (!state.epsilonOnlyTransitions)
         {
             continue;
         }
         foreach (Transition transition in state.Transitions)
         {
             if (transition.TransitionType != TransitionType.Rule)
             {
                 continue;
             }
             RuleTransition ruleTransition = (RuleTransition)transition;
             relations.AddRuleInvocation(state.ruleIndex, ruleTransition.target.ruleIndex);
         }
     }
     return relations;
 }