private void CheckDependencies(IList <Tuple <RuleDependency, IElement> > dependencies, ITypeMirror recognizerType) { string[] ruleNames = GetRuleNames(recognizerType); int[] ruleVersions = GetRuleVersions(recognizerType, ruleNames); RuleDependencyProcessor.RuleRelations relations = ExtractRuleRelations(recognizerType); foreach (Tuple <RuleDependency, IElement> dependency in dependencies) { try { if (!processingEnv.GetTypeUtils().IsAssignable(GetRecognizerType(dependency.Item1), 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) { Tuple <IAnnotationMirror, IAnnotationValue> ruleReferenceElement = FindRuleDependencyProperty(dependency, RuleDependencyProcessor.RuleDependencyProperty.Rule); string message = string.Format("Rule dependency on unknown rule {0}@{1} in {2}", dependency.Item1.Rule(), dependency.Item1.Version(), GetRecognizerType(dependency.Item1).ToString()); if (ruleReferenceElement != null) { processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency.Item2, ruleReferenceElement.Item1, ruleReferenceElement.Item2); } else { processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency.Item2); } continue; } EnumSet <Dependents> dependents = EnumSet.Of(Dependents.Self, dependency.Item1.Dependents()); ReportUnimplementedDependents(dependency, dependents); BitSet @checked = new BitSet(); int highestRequiredDependency = CheckDependencyVersion(dependency, ruleNames, ruleVersions, effectiveRule, null); if (dependents.Contains(Dependents.Parents)) { 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(dependency, ruleNames, ruleVersions, parent, "parent"); highestRequiredDependency = Math.Max(highestRequiredDependency, required); } } if (dependents.Contains(Dependents.Children)) { 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(dependency, ruleNames, ruleVersions, child, "child"); highestRequiredDependency = Math.Max(highestRequiredDependency, required); } } if (dependents.Contains(Dependents.Ancestors)) { 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(dependency, ruleNames, ruleVersions, ancestor, "ancestor"); highestRequiredDependency = Math.Max(highestRequiredDependency, required); } } if (dependents.Contains(Dependents.Descendants)) { 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(dependency, ruleNames, ruleVersions, descendant, "descendant"); highestRequiredDependency = Math.Max(highestRequiredDependency, required); } } int declaredVersion = dependency.Item1.Version(); if (declaredVersion > highestRequiredDependency) { Tuple <IAnnotationMirror, IAnnotationValue> versionElement = FindRuleDependencyProperty(dependency, RuleDependencyProcessor.RuleDependencyProperty.Version); string message = string.Format("Rule dependency version mismatch: {0} has maximum dependency version {1} (expected {2}) in {3}", ruleNames[dependency.Item1.Rule()], highestRequiredDependency, declaredVersion, GetRecognizerType(dependency.Item1).ToString()); if (versionElement != null) { processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency.Item2, versionElement.Item1, versionElement.Item2); } else { processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency.Item2); } } } catch (AnnotationTypeMismatchException) { processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, string.Format("Could not validate rule dependencies for element {0}", dependency.Item2.ToString()), dependency.Item2); } } }