diff --git a/tools/generator/ApiFixup.cs b/tools/generator/ApiFixup.cs index 54081c572..e8d52c026 100644 --- a/tools/generator/ApiFixup.cs +++ b/tools/generator/ApiFixup.cs @@ -91,10 +91,10 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) api_node.ParentNode.RemoveChild (api_node); if (matches.Count == 0) // BG8A00 - Report.Warning (0, Report.WarningApiFixup + 0, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 0, null, metanav, " matched no nodes.", path); } catch (XPathException e) { // BG4A01 - Report.Error (Report.ErrorApiFixup + 1, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 1, e, metanav, "Invalid XPath specification: {0}", path); } break; case "add-node": @@ -109,10 +109,10 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) } if (!matched) // BG8A01 - Report.Warning (0, Report.WarningApiFixup + 1, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 1, null, metanav, " matched no nodes.", path); } catch (XPathException e) { // BG4A02 - Report.Error (Report.ErrorApiFixup + 2, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 2, e, metanav, "Invalid XPath specification: {0}", path); } break; case "change-node": @@ -135,10 +135,10 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) if (!matched) // BG8A03 - Report.Warning (0, Report.WarningApiFixup + 3, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 3, null, metanav, " matched no nodes.", path); } catch (XPathException e) { // BG4A03 - Report.Error (Report.ErrorApiFixup + 3, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 3, e, metanav, "Invalid XPath specification: {0}", path); } break; case "attr": @@ -146,7 +146,7 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) string attr_name = metanav.XGetAttribute ("name", ""); if (string.IsNullOrEmpty (attr_name)) // BG4A07 - Report.Error (Report.ErrorApiFixup + 7, "Target attribute name is not specified for path: {0}", path); + Report.Error (Report.ErrorApiFixup + 7, null, metanav, "Target attribute name is not specified for path: {0}", path); var nodes = attr_last_cache != null ? (IEnumerable) new XPathNavigator [] {attr_last_cache} : api_nav.Select (path).OfType (); @@ -159,12 +159,12 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) } if (attr_matched == 0) // BG8A04 - Report.Warning (0, Report.WarningApiFixup + 4, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 4, null, metanav, " matched no nodes.", path); if (attr_matched != 1) attr_last_cache = null; } catch (XPathException e) { // BG4A04 - Report.Error (Report.ErrorApiFixup + 4, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 4, e, metanav, "Invalid XPath specification: {0}", path); } break; case "move-node": @@ -185,10 +185,10 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) } if (!matched) // BG8A05 - Report.Warning (0, Report.WarningApiFixup + 5, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 5, null, metanav, " matched no nodes.", path); } catch (XPathException e) { // BG4A05 - Report.Error (Report.ErrorApiFixup + 5, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 5, e, metanav, "Invalid XPath specification: {0}", path); } break; case "remove-attr": @@ -206,10 +206,10 @@ void Process (XmlDocument meta_doc, string apiLevelString, int productVersion) if (!matched) // BG8A06 - Report.Warning (0, Report.WarningApiFixup + 6, " matched no nodes.", path); + Report.Warning (0, Report.WarningApiFixup + 6, null, metanav, " matched no nodes.", path); } catch (XPathException e) { // BG4A06 - Report.Error (Report.ErrorApiFixup + 6, e, "Invalid XPath specification: {0}", path); + Report.Error (Report.ErrorApiFixup + 6, e, metanav, "Invalid XPath specification: {0}", path); } break; } diff --git a/tools/generator/Report.cs b/tools/generator/Report.cs index f3cce8d98..76b62280d 100644 --- a/tools/generator/Report.cs +++ b/tools/generator/Report.cs @@ -1,5 +1,7 @@ using System; using System.Linq; +using System.Xml; +using System.Xml.XPath; namespace MonoDroid.Generation { @@ -31,25 +33,67 @@ public class Report public static void Error (int errorCode, string format, params object[] args) { - Error (errorCode, null, format, args); + Error (errorCode, null, null, -1, -1, format, args); } - - public static void Error (int errorCode, Exception innerException, string format, params object[] args) + + public static void Error (int errorCode, string sourceFile, int line, int column, string format, params object [] args) { - throw new BindingGeneratorException (errorCode, string.Format (format, args), innerException); + Error (errorCode, null, sourceFile, line, column, format, args); + } + + public static void Error (int errorCode, Exception innerException, string format, params object [] args) + { + Error (errorCode, innerException, null, -1, -1, format, args); + } + + public static void Error (int errorCode, Exception innerException, XPathNavigator nav, string format, params object [] args) + { + var hn = nav as IHasXmlNode; + var baseUri = hn != null ? hn.GetNode ().OwnerDocument.BaseURI : nav.BaseURI; + Uri uri; + string file = Uri.TryCreate (baseUri, UriKind.Absolute, out uri) ? uri.LocalPath : null; + IXmlLineInfo li = nav as IXmlLineInfo; + li = li != null && li.HasLineInfo () ? li : null; + Error (errorCode, innerException, file, li != null ? li.LineNumber : -1, li != null ? li.LinePosition : -1, format, args); + } + + public static void Error (int errorCode, Exception innerException, string sourceFile, int line, int column, string format, params object[] args) + { + throw new BindingGeneratorException (errorCode, sourceFile, line, column, string.Format (format, args), innerException); } public static void Warning (int verbosity, int errorCode, string format, params object[] args) { Warning (verbosity, errorCode, null, format, args); } + + public static void Warning (int verbosity, int errorCode, Exception innerException, XPathNavigator nav, string format, params object [] args) + { + var hn = nav as IHasXmlNode; + var baseUri = hn != null ? hn.GetNode ().OwnerDocument.BaseURI : nav.BaseURI; + Uri uri; + string file = Uri.TryCreate (baseUri, UriKind.Absolute, out uri) ? uri.LocalPath : null; + IXmlLineInfo li = nav as IXmlLineInfo; + li = li != null && li.HasLineInfo () ? li : null; + Warning (verbosity, errorCode, innerException, file, li != null ? li.LineNumber : -1, li != null ? li.LinePosition : -1, format, args); + } + + public static void Warning (int verbosity, int errorCode, string sourceFile, int line, int column, string format, params object[] args) + { + Warning (verbosity, errorCode, null, sourceFile, line, column, format, args); + } + + public static void Warning (int verbosity, int errorCode, Exception innerException, string format, params object [] args) + { + Warning (verbosity, errorCode, innerException, null, -1, -1, format, args); + } - public static void Warning (int verbosity, int errorCode, Exception innerException, string format, params object[] args) + public static void Warning (int verbosity, int errorCode, Exception innerException, string sourceFile, int line, int column, string format, params object[] args) { if (verbosity > (Verbosity ?? 0)) return; string supp = innerException != null ? " For details, see verbose output." : null; - Console.Error.WriteLine (Format (false, errorCode, format, args) + supp); + Console.Error.WriteLine (Format (false, errorCode, sourceFile, line, column, format, args) + supp); if (innerException != null) Console.Error.WriteLine (innerException); } @@ -60,10 +104,16 @@ public static void Verbose (int verbosity, string format, params object[] args) return; Console.Error.WriteLine (format, args); } + + public static string Format (bool error, int errorCode, string format, params object [] args) + { + return Format (error, errorCode, null, -1, -1, format, args); + } - public static string Format (bool error, int errorCode, string format, params object[] args) + public static string Format (bool error, int errorCode, string sourceFile, int line, int column, string format, params object[] args) { - return string.Format ("{0}{1} BG{2:X04}: ", "" /* origin? */, error ? "error" : "warning", errorCode) + + var origin = sourceFile != null ? sourceFile + (line > 0 ? column > 0 ? $"({line}, {column})" : $"({line})" : null) + ' ' : null; + return string.Format ("{0}{1} BG{2:X04}: ", origin, error ? "error" : "warning", errorCode) + string.Format (format, args); } } @@ -75,7 +125,11 @@ public BindingGeneratorException (int errorCode, string message) { } public BindingGeneratorException (int errorCode, string message, Exception innerException) - : base (Report.Format (true, errorCode, message), innerException) + : this (errorCode, null, -1, -1, message, innerException) + { + } + public BindingGeneratorException (int errorCode, string sourceFile, int line, int column, string message, Exception innerException) + : base (Report.Format (true, errorCode, sourceFile, line, column, message), innerException) { } }