-
Notifications
You must be signed in to change notification settings - Fork 64
[generator] Add support for <ns-replace> metadata. #939
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| using System.Xml.Linq; | ||
|
|
||
| using Xamarin.Android.Tools; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Java.Interop.Tools.Generator | ||
| { | ||
|
|
@@ -168,6 +169,18 @@ public void Apply (ApiXmlDocument apiDocument, string apiLevelString, int produc | |
| } | ||
| } | ||
|
|
||
| public IList<NamespaceTransform> GetNamespaceTransforms () | ||
| { | ||
| var list = new List<NamespaceTransform> (); | ||
|
|
||
| foreach (var xe in FixupDocument.XPathSelectElements ("/metadata/ns-replace")) { | ||
| if (NamespaceTransform.TryParse (xe, out var transform)) | ||
| list.Add (transform); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What should happen if there's a duplicate? Should we care? Emit a warning? Particularly if we're thinking of adding
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fine to ignore duplicates, we do the same for other I'm not aware of any plan to add |
||
| } | ||
|
|
||
| return list; | ||
| } | ||
|
|
||
| bool ShouldSkip (XElement node, int apiLevel, int productVersion) | ||
| { | ||
| if (apiLevel > 0) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Xml.Linq; | ||
| using Xamarin.Android.Tools; | ||
|
|
||
| namespace Java.Interop.Tools.Generator | ||
| { | ||
| public class NamespaceTransform | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rando aside: would this be a good use case for C#9
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't look like you can override primary constructors (?!), so this isn't a good use case.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However, you can still use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading through the link, I don't see any benefits to using |
||
| { | ||
| public string OldValue { get; } | ||
| public string NewValue { get; } | ||
| public bool IsStartsWith { get; } | ||
| public bool IsEndsWith { get; } | ||
|
|
||
| public NamespaceTransform (string oldValue, string newValue) | ||
| { | ||
| OldValue = oldValue; | ||
| NewValue = newValue; | ||
|
|
||
| if (OldValue.EndsWith (".", StringComparison.Ordinal)) { | ||
jonpryor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| IsStartsWith = true; | ||
| OldValue = OldValue.Substring (0, OldValue.Length - 1); | ||
| } | ||
|
|
||
| if (OldValue.StartsWith (".", StringComparison.Ordinal)) { | ||
| IsEndsWith = true; | ||
| OldValue = OldValue.Substring (1); | ||
| } | ||
| } | ||
|
|
||
| public string ApplyInternal (string value) | ||
| { | ||
| string result; | ||
|
|
||
| while (true) { | ||
| result = ApplyInternal (value); | ||
|
|
||
| if (result == value) | ||
| return result; | ||
|
|
||
| value = result; | ||
| } | ||
| } | ||
|
|
||
| public string Apply (string value) | ||
| { | ||
| // Handle a "starts with" and "ends with" transform | ||
| if (IsStartsWith && IsEndsWith) { | ||
| if (value.Equals (OldValue, StringComparison.OrdinalIgnoreCase)) | ||
| return NewValue; | ||
|
|
||
| // Don't let this fall through | ||
| return value; | ||
| } | ||
|
|
||
| // Handle a "starts with" transform | ||
| if (IsStartsWith) { | ||
| if (value.StartsWith (OldValue, StringComparison.OrdinalIgnoreCase)) | ||
| return (NewValue + value.Substring (OldValue.Length)).TrimStart ('.'); | ||
jonpryor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| return value; | ||
| } | ||
|
|
||
| // Handle an "ends with" transform | ||
| if (IsEndsWith) { | ||
| if (value.EndsWith (OldValue, StringComparison.OrdinalIgnoreCase)) | ||
| return (value.Substring (0, value.Length - OldValue.Length) + NewValue).TrimEnd ('.'); | ||
|
|
||
| return value; | ||
| } | ||
|
|
||
| // Handle an "anywhere" transform | ||
| var value_tokens = value.Split ('.'); | ||
| var match_tokens = OldValue.Split ('.'); | ||
|
|
||
| var results = new List<string> (); | ||
|
|
||
| for (var i = 0; i < value_tokens.Length; i++) { | ||
| if (AtMatch (value_tokens, i, match_tokens, 0)) { | ||
| if (NewValue.HasValue ()) | ||
| results.Add (NewValue); | ||
|
|
||
| i += match_tokens.Length - 1; | ||
| } else { | ||
| results.Add (value_tokens [i]); | ||
| } | ||
| } | ||
|
|
||
| return string.Join (".", results); | ||
| } | ||
|
|
||
| public static bool TryParse (XElement element, [NotNullWhen (true)] out NamespaceTransform? transform) | ||
| { | ||
| var source = element.XGetAttribute ("source"); | ||
| var replacement = element.XGetAttribute ("replacement"); | ||
|
|
||
| if (!source.HasValue () || replacement is null) { | ||
| Report.LogCodedWarning (0, Report.WarningInvalidNamespaceTransform, null, element, element.ToString ()); | ||
| transform = null; | ||
| return false; | ||
| } | ||
|
|
||
| transform = new NamespaceTransform (source, replacement); | ||
| return true; | ||
| } | ||
|
|
||
| private bool AtMatch (string [] valueTokens, int valueIndex, string [] matchTokens, int matchIndex) | ||
| { | ||
| if (matchIndex >= matchTokens.Length) | ||
| return true; | ||
|
|
||
| if (valueIndex >= valueTokens.Length) | ||
| return false; | ||
|
|
||
| if (string.Compare (valueTokens [valueIndex], matchTokens [matchIndex], StringComparison.OrdinalIgnoreCase) == 0) | ||
| return AtMatch (valueTokens, valueIndex + 1, matchTokens, matchIndex + 1); | ||
|
|
||
| return false; | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a
List<T>, or should it be aHashSet<T>?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order is significant, so we need to stick with
List.