diff --git a/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs b/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs
index 0578fd258..96b4bcfa4 100644
--- a/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs
+++ b/src/Java.Interop.Tools.Generator/Metadata/FixupXmlDocument.cs
@@ -58,9 +58,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
else
// BG8A00
Report.LogCodedWarning (0, Report.WarningRemoveNodeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4301
- Report.LogCodedError (Report.ErrorRemoveNodeInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorRemoveNodeInvalidXPath, metaitem, path);
}
break;
case "add-node":
@@ -74,9 +74,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
foreach (var node in nodes)
node.Add (metaitem.Nodes ());
}
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4302
- Report.LogCodedError (Report.ErrorAddNodeInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorAddNodeInvalidXPath, metaitem, path);
}
break;
case "change-node":
@@ -95,9 +95,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
if (!matched)
// BG8A03
Report.LogCodedWarning (0, Report.WarningChangeNodeTypeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4303
- Report.LogCodedError (Report.ErrorChangeNodeInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorChangeNodeInvalidXPath, metaitem, path);
}
break;
case "attr":
@@ -106,7 +106,7 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
if (string.IsNullOrEmpty (attr_name))
// BG4307
- Report.LogCodedError (Report.ErrorMissingAttrName, null, metaitem, path);
+ Report.LogCodedError (Report.ErrorMissingAttrName, metaitem, path);
var nodes = attr_last_cache != null ? new XElement [] { attr_last_cache } : apiDocument.ApiDocument.XPathSelectElements (path);
var attr_matched = 0;
@@ -119,9 +119,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
Report.LogCodedWarning (0, Report.WarningAttrMatchedNoNodes, null, metaitem, $"");
if (attr_matched != 1)
attr_last_cache = null;
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4304
- Report.LogCodedError (Report.ErrorAttrInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorAttrInvalidXPath, metaitem, path);
}
break;
case "move-node":
@@ -140,9 +140,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
if (!matched)
// BG8A05
Report.LogCodedWarning (0, Report.WarningMoveNodeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4305
- Report.LogCodedError (Report.ErrorMoveNodeInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorMoveNodeInvalidXPath, metaitem, path);
}
break;
case "remove-attr":
@@ -159,9 +159,9 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc
if (!matched)
// BG8A06
Report.LogCodedWarning (0, Report.WarningRemoveAttrMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
+ } catch (XPathException) {
// BG4306
- Report.LogCodedError (Report.ErrorRemoveAttrInvalidXPath, e, metaitem, path);
+ Report.LogCodedError (Report.ErrorRemoveAttrInvalidXPath, metaitem, path);
}
break;
}
diff --git a/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs b/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs
index 1bd333165..42f6a4f1b 100644
--- a/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs
+++ b/src/Java.Interop.Tools.Generator/Utilities/ApiXmlDocument.cs
@@ -40,7 +40,7 @@ public void ApplyFixupFile (FixupXmlDocument fixup)
fixup.Apply (this, ApiLevel, ProductVersion);
} catch (XmlException ex) {
// BG4200
- Report.LogCodedError (Report.ErrorFailedToProcessMetadata, ex.Message);
+ Report.LogCodedErrorAndExit (Report.ErrorFailedToProcessMetadata, null, fixup.FixupDocument, ex.Message);
}
}
}
diff --git a/src/Java.Interop.Tools.Generator/Utilities/Report.cs b/src/Java.Interop.Tools.Generator/Utilities/Report.cs
index e216a1535..c8582d135 100644
--- a/src/Java.Interop.Tools.Generator/Utilities/Report.cs
+++ b/src/Java.Interop.Tools.Generator/Utilities/Report.cs
@@ -69,23 +69,30 @@ public LocalizedMessage (int code, string value)
public static LocalizedMessage WarningBaseInterfaceNotFound => new LocalizedMessage (0x8C00, Localization.Resources.Generator_BG8C00);
public static LocalizedMessage WarningBaseInterfaceInvalid => new LocalizedMessage (0x8C01, Localization.Resources.Generator_BG8C01);
- public static void LogCodedError (LocalizedMessage message, params string [] args)
- => LogCodedError (message, null, null, -1, -1, args);
+ public static void LogCodedErrorAndExit (LocalizedMessage message, params string [] args)
+ => LogCodedErrorAndExit (message, null, null, args);
- public static void LogCodedError (LocalizedMessage message, Exception? innerException, params string [] args)
- => LogCodedError (message, innerException, null, -1, -1, args);
+ public static void LogCodedErrorAndExit (LocalizedMessage message, Exception? innerException, params string [] args)
+ => LogCodedErrorAndExit (message, innerException, null, args);
- public static void LogCodedError (LocalizedMessage message, Exception? innerException, XNode node, params string? [] args)
+ public static void LogCodedErrorAndExit (LocalizedMessage message, Exception? innerException, XNode? node, params string? [] args)
{
- var file = Uri.TryCreate (node.BaseUri, UriKind.Absolute, out var uri) ? uri.LocalPath : null;
- var line_info = (node as IXmlLineInfo)?.HasLineInfo () == true ? node as IXmlLineInfo : null;
+ LogCodedError (message, node, args);
- LogCodedError (message, innerException, file, line_info?.LineNumber ?? -1, line_info?.LinePosition ?? -1, args);
+ // Throwing a BindingGeneratorException will cause generator to terminate
+ throw new BindingGeneratorException (message.Code, string.Format (message.Value, args), innerException);
}
- public static void LogCodedError (LocalizedMessage message, Exception? innerException, string? sourceFile, int line, int column, params string? [] args)
+ public static void LogCodedError (LocalizedMessage message, XNode? node, params string? [] args)
{
- throw new BindingGeneratorException (message.Code, sourceFile, line, column, string.Format (message.Value, args), innerException);
+ var (file, line, col) = GetLineInfo (node);
+
+ LogCodedError (message, file, line, col, args);
+ }
+
+ public static void LogCodedError (LocalizedMessage message, string? sourceFile, int line, int column, params string? [] args)
+ {
+ Console.Error.WriteLine (Format (true, message.Code, sourceFile, line, column, message.Value, args));
}
public static void LogCodedWarning (int verbosity, LocalizedMessage message, params string? [] args)
@@ -99,10 +106,9 @@ public static void LogCodedWarning (int verbosity, LocalizedMessage message, Exc
public static void LogCodedWarning (int verbosity, LocalizedMessage message, Exception? innerException, XNode node, params string? [] args)
{
- var file = Uri.TryCreate (node.BaseUri, UriKind.Absolute, out var uri) ? uri.LocalPath : null;
- var line_info = (node as IXmlLineInfo)?.HasLineInfo () == true ? node as IXmlLineInfo : null;
+ var (file, line, col) = GetLineInfo (node);
- LogCodedWarning (verbosity, message, innerException, file, line_info?.LineNumber ?? -1, line_info?.LinePosition ?? -1, args);
+ LogCodedWarning (verbosity, message, innerException, file, line, col, args);
}
public static void LogCodedWarning (int verbosity, LocalizedMessage message, Exception? innerException, string? sourceFile, int line, int column, params string? [] args)
@@ -145,12 +151,26 @@ public static string Format (bool error, int errorCode, string? sourceFile, int
return ret + ": ";
if (column > 0)
- return ret + $"({line}, {column}): ";
+ return ret + $"({line},{column}): ";
return ret + $"({line}): ";
}
+
+ static (string? file, int line, int col) GetLineInfo (XNode? node)
+ {
+ if (node is null)
+ return (null, -1, -1);
+
+ var file = Uri.TryCreate (node.BaseUri, UriKind.Absolute, out var uri) ? uri.LocalPath : null;
+ var pos = (node as IXmlLineInfo)?.HasLineInfo () == true ? node as IXmlLineInfo : null;
+
+ return (file, pos?.LineNumber ?? -1, pos?.LinePosition ?? -1);
+ }
}
-
+
+ ///
+ /// Throwing this exception will cause generator to exit gracefully.
+ ///
public class BindingGeneratorException : Exception
{
public BindingGeneratorException (int errorCode, string message)
diff --git a/tests/generator-Tests/Unit-Tests/ReportTests.cs b/tests/generator-Tests/Unit-Tests/ReportTests.cs
index cdb4925df..65a73e3ad 100644
--- a/tests/generator-Tests/Unit-Tests/ReportTests.cs
+++ b/tests/generator-Tests/Unit-Tests/ReportTests.cs
@@ -24,8 +24,8 @@ public void FormatTests ()
Assert.AreEqual ("error BG0037: There was a bad error", Report.Format (true, code, null, 0, 0, msg, args));
Assert.AreEqual (@"C:\code\test.cs: error BG0037: There was a bad error", Report.Format (true, code, sourcefile, 0, 0, msg, args));
Assert.AreEqual (@"C:\code\test.cs(32): error BG0037: There was a bad error", Report.Format (true, code, sourcefile, line, 0, msg, args));
- Assert.AreEqual (@"C:\code\test.cs(32, 12): error BG0037: There was a bad error", Report.Format (true, code, sourcefile, line, col, msg, args));
- Assert.AreEqual (@"C:\code\test.cs(32, 12): warning BG0037: There was a bad error", Report.Format (false, code, sourcefile, line, col, msg, args));
+ Assert.AreEqual (@"C:\code\test.cs(32,12): error BG0037: There was a bad error", Report.Format (true, code, sourcefile, line, col, msg, args));
+ Assert.AreEqual (@"C:\code\test.cs(32,12): warning BG0037: There was a bad error", Report.Format (false, code, sourcefile, line, col, msg, args));
}
}
}
diff --git a/tools/generator/CodeGenerationOptions.cs b/tools/generator/CodeGenerationOptions.cs
index 515b3585d..e483cf0a1 100644
--- a/tools/generator/CodeGenerationOptions.cs
+++ b/tools/generator/CodeGenerationOptions.cs
@@ -222,7 +222,7 @@ public string GetOutputName (string type)
if (type.StartsWith ("params "))
return "params " + GetOutputName (type.Substring ("params ".Length));
if (type.StartsWith ("global::"))
- Report.LogCodedError (Report.ErrorUnexpectedGlobal);
+ Report.LogCodedErrorAndExit (Report.ErrorUnexpectedGlobal);
if (!UseGlobal)
return type;
diff --git a/tools/generator/CodeGenerator.cs b/tools/generator/CodeGenerator.cs
index 2f8fc1cc8..b79ea12b5 100644
--- a/tools/generator/CodeGenerator.cs
+++ b/tools/generator/CodeGenerator.cs
@@ -22,11 +22,19 @@ public class CodeGenerator
{
public static int Main (string[] args)
{
- var options = CodeGeneratorOptions.Parse (args);
- if (options == null)
+ try {
+ var options = CodeGeneratorOptions.Parse (args);
+ if (options == null)
+ return 1;
+
+ Run (options);
+ } catch (BindingGeneratorException) {
return 1;
+ } catch (Exception ex) {
+ Console.Error.WriteLine (Report.Format (true, 0, null, -1, -1, ex.ToString ()));
+ return 1;
+ }
- Run (options);
return 0;
}
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/ApiFixup.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/ApiFixup.cs
deleted file mode 100644
index f9500d368..000000000
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/ApiFixup.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Xml;
-using System.Xml.XPath;
-using System.Xml.Linq;
-
-using Xamarin.Android.Tools;
-using Java.Interop.Tools.Generator;
-
-namespace MonoDroid.Generation
-{
- public class ApiFixup
- {
- XDocument api_doc;
- string apiSource = "";
-
- public string ApiSource { get { return apiSource; } }
-
- public ApiFixup (XDocument apiDoc)
- {
- api_doc = apiDoc;
- var api = api_doc.Root;
- if (api != null)
- apiSource = api.XGetAttribute ("api-source");
- }
-
- public void Process (IEnumerable metaDocs, string apiLevel, int productVersion)
- {
- foreach (var metaDoc in metaDocs)
- Process (metaDoc, apiLevel, productVersion);
- }
-
- bool ShouldSkip (XElement node, int apiLevel, int productVersion)
- {
- if (apiLevel > 0) {
- string apiSince = node.XGetAttribute ("api-since");
- string apiUntil = node.XGetAttribute ("api-until");
- if (!string.IsNullOrEmpty (apiSince) && int.Parse (apiSince) > apiLevel)
- return true;
- if (!string.IsNullOrEmpty (apiUntil) && int.Parse (apiUntil) < apiLevel)
- return true;
- }
- if (productVersion > 0) {
- var product_version = node.XGetAttribute ("product-version");
- if (!string.IsNullOrEmpty (product_version) && int.Parse (product_version) > productVersion)
- return true;
- }
- return false;
- }
-
- bool ShouldApply (XElement node)
- {
- if (!string.IsNullOrEmpty (apiSource)) {
- var targetsource = node.XGetAttribute ("api-source");
- if (string.IsNullOrEmpty (targetsource))
- return true;
- return targetsource == apiSource;
- }
- return true;
- }
-
- void Process (XDocument meta_doc, string apiLevelString, int productVersion)
- {
- int apiLevel = 0;
- int.TryParse (apiLevelString, out apiLevel);
-
- var metadataChildren = meta_doc.XPathSelectElements ("/metadata/*");
- string prev_path = null;
- XElement attr_last_cache = null;
-
- foreach (var metaitem in metadataChildren) {
- if (ShouldSkip (metaitem, apiLevel, productVersion))
- continue;
- if (!ShouldApply (metaitem))
- continue;
- string path = metaitem.XGetAttribute ("path");
- if (path != prev_path)
- attr_last_cache = null;
- prev_path = path;
-
- switch (metaitem.Name.LocalName) {
- case "remove-node":
- try {
- var nodes = api_doc.XPathSelectElements (path).ToArray ();
- if (nodes.Any ())
- foreach (var node in nodes)
- node.Remove ();
- else
- // BG8A00
- Report.LogCodedWarning (0, Report.WarningRemoveNodeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
- // BG4301
- Report.LogCodedError (Report.ErrorRemoveNodeInvalidXPath, e, metaitem, path);
- }
- break;
- case "add-node":
- try {
- var nodes = api_doc.XPathSelectElements (path);
- if (!nodes.Any ())
- // BG8A01
- Report.LogCodedWarning (0, Report.WarningAddNodeMatchedNoNodes, null, metaitem, $"");
- else {
- foreach (var node in nodes)
- node.Add (metaitem.Nodes ());
- }
- } catch (XPathException e) {
- // BG4302
- Report.LogCodedError (Report.ErrorAddNodeInvalidXPath, e, metaitem, path);
- }
- break;
- case "change-node":
- try {
- var nodes = api_doc.XPathSelectElements (path);
- bool matched = false;
- foreach (var node in nodes) {
- var newChild = new XElement (metaitem.Value);
- newChild.Add (node.Attributes ());
- newChild.Add (node.Nodes ());
- node.ReplaceWith (newChild);
- matched = true;
- }
-
- if (!matched)
- // BG8A03
- Report.LogCodedWarning (0, Report.WarningChangeNodeTypeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
- // BG4303
- Report.LogCodedError (Report.ErrorChangeNodeInvalidXPath, e, metaitem, path);
- }
- break;
- case "attr":
- try {
- string attr_name = metaitem.XGetAttribute ("name");
- if (string.IsNullOrEmpty (attr_name))
- // BG4307
- Report.LogCodedError (Report.ErrorMissingAttrName, null, metaitem, path);
- var nodes = attr_last_cache != null ? new XElement [] { attr_last_cache } : api_doc.XPathSelectElements (path);
- int attr_matched = 0;
- foreach (var n in nodes) {
- n.SetAttributeValue (attr_name, metaitem.Value);
- attr_matched++;
- }
- if (attr_matched == 0)
- // BG8A04
- Report.LogCodedWarning (0, Report.WarningAttrMatchedNoNodes, null, metaitem, $"");
- if (attr_matched != 1)
- attr_last_cache = null;
- } catch (XPathException e) {
- // BG4304
- Report.LogCodedError (Report.ErrorAttrInvalidXPath, e, metaitem, path);
- }
- break;
- case "move-node":
- try {
- string parent = metaitem.Value;
- var parents = api_doc.XPathSelectElements (parent);
- bool matched = false;
- foreach (var parent_node in parents) {
- var nodes = parent_node.XPathSelectElements (path).ToArray ();
- foreach (var node in nodes)
- node.Remove ();
- parent_node.Add (nodes);
- matched = true;
- }
- if (!matched)
- // BG8A05
- Report.LogCodedWarning (0, Report.WarningMoveNodeMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
- // BG4305
- Report.LogCodedError (Report.ErrorMoveNodeInvalidXPath, e, metaitem, path);
- }
- break;
- case "remove-attr":
- try {
- string name = metaitem.XGetAttribute ("name");
- var nodes = api_doc.XPathSelectElements (path);
- bool matched = false;
-
- foreach (var node in nodes) {
- node.RemoveAttributes ();
- matched = true;
- }
-
- if (!matched)
- // BG8A06
- Report.LogCodedWarning (0, Report.WarningRemoveAttrMatchedNoNodes, null, metaitem, $"");
- } catch (XPathException e) {
- // BG4306
- Report.LogCodedError (Report.ErrorRemoveAttrInvalidXPath, e, metaitem, path);
- }
- break;
- }
- }
- }
- }
-}
-
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMap.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMap.cs
index 43d6f6513..c0bb534b7 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMap.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMap.cs
@@ -66,7 +66,7 @@ void RemoveOldConstants (StreamWriter sw)
sw.WriteLine (" ",
package, type, member, enu.StartsWith ("I:") ? "interface" : "class");
} catch (Exception ex) {
- Report.LogCodedError (Report.ErrorFailedToRemoveConstants, ex, enu);
+ Report.LogCodedErrorAndExit (Report.ErrorFailedToRemoveConstants, ex, enu);
throw;
}
}
@@ -93,7 +93,7 @@ void FixOldConstants (StreamWriter sw)
sw.WriteLine (" ",
package, type, member, enu.StartsWith ("I:") ? "interface" : "class");
} catch (Exception ex) {
- Report.LogCodedError (Report.ErrorFailedToRemoveConstants, ex, enu);
+ Report.LogCodedErrorAndExit (Report.ErrorFailedToRemoveConstants, ex, enu);
throw;
}
}
diff --git a/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMappings.cs b/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMappings.cs
index 677e174ba..be84e6949 100644
--- a/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMappings.cs
+++ b/tools/generator/Java.Interop.Tools.Generator.Transformation/EnumMappings.cs
@@ -222,7 +222,7 @@ internal List ParseMethodMappings (TextReader source, int filter_v
try {
list.Add (new ApiTransform (preserveTypeMode, items));
} catch (Exception ex) {
- Report.LogCodedError (Report.ErrorFailedToProcessEnumMap, ex, s);
+ Report.LogCodedErrorAndExit (Report.ErrorFailedToProcessEnumMap, ex, s);
throw;
}
}