static void OutputResults(CollectionResolutionResults results, string xmlFile, string outputXmlFile) { if (results.Count == 0) { return; } var source = new SourceLineInfo(xmlFile); var first_cycle = results.First(); // The first cycle is more interesting to the user, as it is mainly external Java types // that could not be resolved, which often point to a missing reference jar or NuGet. // Thus, we're going to output these as warnings. var missing_types = first_cycle.Unresolvables.Select(u => u.MissingType).Distinct().OrderBy(t => t); foreach (var type in missing_types) { Report.LogCodedWarning(0, Report.WarningJavaTypeNotResolved, source, type); } // The remaining cycles are generally just user types that are being removed because // other user types have been removed. Since the root cause is actually the missing external // types above, these aren't as important. We'll write them to a diagnostic file // for the user to inspect for details if they want. var report_file = Path.Combine(Path.GetDirectoryName(outputXmlFile), "java-resolution-report.log"); using (var tw = File.CreateText(report_file)) { for (var i = 0; i < results.Count; i++) { WriteCycle(tw, i + 1, results [i]); } } // Output diagnostic messages to verbose log foreach (var result in results.SelectMany(r => r.Unresolvables)) { Report.Verbose(0, result.GetDisplayMessage()); } // Let users know about this report Report.LogCodedWarning(0, Report.WarningTypesNotBoundDueToMissingJavaTypes, new SourceLineInfo(report_file)); }
/// <summary> /// Ensures all types needed by the binding types can be found. Removes members or types /// that need types that cannot be found. /// </summary> public CollectionResolutionResults ResolveCollection(TypeResolutionOptions?options = null) { options ??= TypeResolutionOptions.Default; var results = new CollectionResolutionResults(); while (true) { var unresolvables = new Collection <JavaUnresolvableModel> (); foreach (var t in Types) { try { t.Value.Resolve(this, unresolvables); } catch (JavaTypeResolutionException) { } } foreach (var u in unresolvables) { if (u.Unresolvable is JavaTypeModel type) { u.RemovedEntireType = RemoveResolvedType(type); } else if (u.Unresolvable is JavaConstructorModel ctor) { // Remove from declaring type (must pattern check for ctor before method) ((JavaClassModel)ctor.DeclaringType).Constructors.Remove(ctor); } else if (u.Unresolvable is JavaMethodModel method) { // Remove from declaring type u.RemovedEntireType = RemoveMethod(method, options); } else if (u.Unresolvable is JavaFieldModel field) { // Remove from declaring type field.DeclaringType.Fields.Remove(field); } else if (u.Unresolvable is JavaParameterModel parameter) { // Remove method from declaring type u.RemovedEntireType = RemoveMethod(parameter.DeclaringMethod, options); } else { // *Shouldn't* be possible throw new Exception($"Encountered unknown IJavaResolvable: '{u.Unresolvable.GetType ().Name}'"); } } if (unresolvables.Any()) { results.Add(new CollectionResolutionResult(unresolvables)); } // We may have removed a type that other types/members reference, so we have // to keep doing this until we do not remove any types. if (!unresolvables.Any(u => u.RemovedEntireType)) { break; } } // Once we have resolved all base classes we can resolve class members foreach (var klass in TypesFlattened.Values.OfType <JavaClassModel> ()) { klass.ResolveBaseMembers(); } return(results); }