protected virtual void GenerateNamespaceMember(HierarchyNamespace ns, HierarchyElement element, string outputDirectory) { FilesystemPath path = Context.OutputPathProvider.GetPathFor(outputDirectory, element); if (String.IsNullOrEmpty(path?.FullPath)) { Logger.Warning($"Unable to generate output for element {element.GetType ().FullName} ({element.GetManagedName (true) ?? element.FullName}) since no full path was given (at {element.GetLocation ()})"); return; } if (path.IsDirectory) { throw new InvalidOperationException($"Namespace member must be written to a file ({ns.FullName})"); } EnsureDirectory(Path.GetDirectoryName(path.FullPath)); CheckOverwrite(path.FullPath); using (Stream fs = File.Open(path.FullPath, FileMode.Create)) { using (StreamWriter writer = new StreamWriter(fs, Context.FileEncoding)) { WriteFileHeader(ns, writer); OutputNamespaceMember(element, writer, path.FullPath); WriteFileFooter(ns, writer); } } }
void Add(Dictionary <string, HierarchyElement> index, string indexName, string typeName, HierarchyElement type) { if (String.IsNullOrEmpty(typeName)) { throw new ArgumentException("must not be null or empty", nameof(typeName)); } if (String.Compare("java.lang.Comparable", typeName, StringComparison.OrdinalIgnoreCase) == 0) { Logger.Debug($"java.lang.Comparable being added: {type} ({type.FullName})"); } //Logger.Verbose ($"Index: trying to add '{typeName}' ({type.GetType ().FullName}), parent: {type.ParentElement?.FullName} ({type.ParentElement?.GetType ()?.FullName})"); HierarchyElement t; if (index.TryGetValue(typeName, out t) && t != null) { // if (t.GetType () == type.GetType ()) // TODO: implement IEquatable<T> on namespaces, // // classes and indexes and don't throw if the two // // objects have actually equal contents // throw new InvalidOperationException ($"Duplicate type entry for type '{typeName}' ({type.GetType ().FullName})' in {indexName} index"); string prefix = TypeToPrefix(type); Logger.Warning($"Duplicate type name '{typeName}' in {indexName} index. Existing entry is of type {t.GetType ().FullName}, new entry of type {type.GetType ().FullName}"); Logger.Debug($"Prefixing new type entry with '{prefix}:'"); // This is necessary because Xamarin.Android adds invoker classes for deprecated // interfaces and, initially, the class has exactly the same Java name as the interface // and only later in the process the interface name is prefixed with 'I' creating a // unique managed type name typeName = $"{prefix}:{typeName}"; } index [typeName] = type; }
public override FilesystemPath GetPathFor(string rootDirectory, HierarchyElement element) { if (String.IsNullOrEmpty(rootDirectory)) { throw new ArgumentException("Must not be null or empty", nameof(rootDirectory)); } if (element == null) { throw new ArgumentNullException(nameof(element)); } switch (element) { case HierarchyNamespace ns: case HierarchyClass klass: case HierarchyInterface iface: case HierarchyEnum enm: break; default: throw new InvalidOperationException($"Unsupported hierarchy type '{element.GetType ()}'"); } Func <string, HierarchyElement, FilesystemPath> getter = null; switch (TreeLayout.NamespaceTreeStyle) { case OutputNamespaceTreeStyle.Single: getter = GetPathFor_Single; break; case OutputNamespaceTreeStyle.Shallow: getter = GetPathFor_Shallow; break; case OutputNamespaceTreeStyle.Deep: getter = GetPathFor_Deep; break; case OutputNamespaceTreeStyle.FirstLevelThenFullShallow: getter = GetPathFor_FirstLevelThenFullShallow; break; case OutputNamespaceTreeStyle.FirstLevelThenFullSingle: getter = GetPathFor_FirstLevelThenFullSingle; break; case OutputNamespaceTreeStyle.FirstLevelThenShortShallow: getter = GetPathFor_FirstLevelThenShortShallow; break; case OutputNamespaceTreeStyle.FirstLevelThenShortSingle: getter = GetPathFor_FirstLevelThenShortSingle; break; default: throw new InvalidOperationException($"Unsupported namespace tree style {TreeLayout.NamespaceTreeStyle}"); } return(getter(rootDirectory, element)); }