[registrar] Add support for specifying that a protocol changed informal status in a certain SDK. Fixes #43780 and #48311. (#2130)

* [registrar] Add support for specifying that a protocol changed informal status in a certain SDK. Fixes #43780

Add support for specifying that an informal protocol became a formal protocol
(or the reverse) in a certain SDK version, so that the static registrar can
generate the correct code based on the SDK being built with.

This also fixes a series of compiler warnings when using the static registrar:

    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:374:11: warning: duplicate protocol definition of 'CALayerDelegate' is ignored
    @protocol CALayerDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/QuartzCore.framework/Headers/CALayer.h:798:11: note: previous definition is here
    @protocol CALayerDelegate <NSObject>
              ^
    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:824:11: warning: duplicate protocol definition of 'WebDownloadDelegate' is ignored
    @protocol WebDownloadDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebDownload.h:60:11: note: previous definition is here
    @protocol WebDownloadDelegate <NSURLDownloadDelegate>
              ^
    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:851:11: warning: duplicate protocol definition of 'WebFrameLoadDelegate' is ignored
    @protocol WebFrameLoadDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebFrameLoadDelegate.h:51:11: note: previous definition is here
    @protocol WebFrameLoadDelegate <NSObject>
              ^
    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:866:11: warning: duplicate protocol definition of 'WebPolicyDelegate' is ignored
    @protocol WebPolicyDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebPolicyDelegate.h:138:11: note: previous definition is here
    @protocol WebPolicyDelegate <NSObject>
              ^
    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:869:11: warning: duplicate protocol definition of 'WebResourceLoadDelegate' is ignored
    @protocol WebResourceLoadDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebResourceLoadDelegate.h:46:11: note: previous definition is here
    @protocol WebResourceLoadDelegate <NSObject>
              ^
    In file included from Xamarin.Mac.registrar.full.i386.m:1:
    ./Xamarin.Mac.registrar.full.i386.h:872:11: warning: duplicate protocol definition of 'WebUIDelegate' is ignored
    @protocol WebUIDelegate
              ^
    /Applications/Xcode83.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/WebKit.framework/Headers/WebUIDelegate.h:153:11: note: previous definition is here
    @protocol WebUIDelegate <NSObject>
              ^

https://bugzilla.xamarin.com/show_bug.cgi?id=43780

* [registrar] Use a string to specify when a protocol went from informal to formal.

Use a string to specify when a protocol went from informal to formal, and
don't support the reverse condition (going from formal to informal), since
it's currently not needed and makes the code more complicated and harder to
understand.

Also add an mtouch test, and update an existing mmp test to be more restrictive.

* [registrar] Rename from 'InformalUntil' to 'FormalSince'.

It just sounds better.
This commit is contained in:
Rolf Bjarne Kvinge 2017-05-29 16:15:54 +02:00 коммит произвёл GitHub
Родитель a32714eb43
Коммит 05895c41f5
9 изменённых файлов: 62 добавлений и 10 удалений

Просмотреть файл

@ -34,6 +34,19 @@ namespace XamCore.Foundation {
public Type WrapperType { get; set; }
public string Name { get; set; }
public bool IsInformal { get; set; }
// In which SDK version this protocol switched from being informal (i.e. a category) to a formal protocol.
// System.Version is not a valid type for attributes, so we're using a string instead.
string informal_until;
public string FormalSince {
get {
return informal_until;
}
set {
if (value != null)
Version.Parse (value); // This will throw an exception with invalid input, which is what we want.
informal_until = value;
}
}
}
[AttributeUsage (AttributeTargets.Interface, AllowMultiple = true)]

Просмотреть файл

@ -1485,6 +1485,11 @@ namespace XamCore.Registrar {
var pAttr = GetProtocolAttribute (type);
isInformalProtocol = pAttr.IsInformal;
isProtocol = true;
#if MMP || MTOUCH
if (pAttr.FormalSinceVersion != null && pAttr.FormalSinceVersion > App.SdkVersion)
isInformalProtocol = !isInformalProtocol;
#endif
}
// make sure the base type is already registered

Просмотреть файл

@ -858,7 +858,15 @@ namespace XamCore.CoreAnimation {
[BaseType (typeof (NSObject))]
[Model]
[Protocol (IsInformal = true)] // not informal as of iOS 10+, but removing the IsInformal value breaks when building with older SDKs (see bug #43585).
#if IOS || TVOS
[Protocol (FormalSince = "10.0")]
#elif MONOMAC
[Protocol (FormalSince = "10.12")]
#elif WATCH
[Protocol (FormalSince = "3.0"]
#else
[Protocol]
#endif
interface CALayerDelegate {
[Export ("displayLayer:")]
void DisplayLayer (CALayer layer);

Просмотреть файл

@ -5159,7 +5159,11 @@ public partial class Generator : IMemberGatherer {
var requiredInstanceAsyncMethods = requiredInstanceMethods.Where (m => AttributeManager.HasAttribute<AsyncAttribute> (m)).ToList ();
PrintAttributes (type, platform:true, preserve:true, advice:true);
print ("[Protocol (Name = \"{1}\", WrapperType = typeof ({0}Wrapper){2})]", TypeName, protocol_name, protocolAttribute.IsInformal ? ", IsInformal = true" : string.Empty);
print ("[Protocol (Name = \"{1}\", WrapperType = typeof ({0}Wrapper){2}{3})]",
TypeName,
protocol_name,
protocolAttribute.IsInformal ? ", IsInformal = true" : string.Empty,
protocolAttribute.FormalSince != null ? $", FormalSince = \"{protocolAttribute.FormalSince}\"" : string.Empty);
var sb = new StringBuilder ();

Просмотреть файл

@ -1817,7 +1817,7 @@ namespace XamCore.WebKit {
[BaseType (typeof (NSObject))]
[Model]
[Protocol (IsInformal = true)]
[Protocol (FormalSince = "10.11")]
partial interface WebDownloadDelegate {
[Export ("downloadWindowForAuthenticationSheet:"), DelegateName ("WebDownloadRequest"), DefaultValue (null)]
NSWindow OnDownloadWindowForSheet (WebDownload download);
@ -1897,7 +1897,7 @@ namespace XamCore.WebKit {
}
[Model]
[Protocol (IsInformal = true)]
[Protocol (FormalSince = "10.11")]
[BaseType (typeof (NSObject))]
partial interface WebFrameLoadDelegate {
[Export ("webView:didStartProvisionalLoadForFrame:"), EventArgs ("WebFrame")]
@ -2060,7 +2060,7 @@ namespace XamCore.WebKit {
[BaseType (typeof (NSObject))]
[Model]
[Protocol (IsInformal = true)]
[Protocol (FormalSince = "10.11")]
partial interface WebPolicyDelegate {
[Export ("webView:decidePolicyForNavigationAction:request:frame:decisionListener:"), EventArgs ("WebNavigationPolicy")]
void DecidePolicyForNavigation (WebView webView, NSDictionary actionInformation, NSUrlRequest request, WebFrame frame, NSObject decisionToken);
@ -2204,7 +2204,7 @@ namespace XamCore.WebKit {
[BaseType (typeof (NSObject))]
[Model]
[Protocol (IsInformal = true)]
[Protocol (FormalSince = "10.11")]
partial interface WebResourceLoadDelegate {
[Export ("webView:identifierForInitialRequest:fromDataSource:"), DelegateName ("WebResourceIdentifierRequest"), DefaultValue (null)]
NSObject OnIdentifierForInitialRequest (WebView sender, NSUrlRequest request, WebDataSource dataSource);
@ -2236,7 +2236,7 @@ namespace XamCore.WebKit {
[BaseType (typeof (NSObject))]
[Model]
[Protocol (IsInformal = true)]
[Protocol (FormalSince = "10.11")]
partial interface WebUIDelegate {
[Export ("webView:createWebViewWithRequest:"), DelegateName("CreateWebViewFromRequest"), DefaultValue (null)]
WebView UICreateWebView (WebView sender, NSUrlRequest request);

Просмотреть файл

@ -36,7 +36,7 @@ namespace Xamarin.Tests
public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds (60);
public IEnumerable<ToolMessage> Messages { get { return messages; } }
List<string> OutputLines {
public List<string> OutputLines {
get {
if (output_lines == null) {
output_lines = new List<string> ();

Просмотреть файл

@ -197,9 +197,8 @@ namespace Xamarin.MMP.Tests
TI.UnifiedTestConfig test = new TI.UnifiedTestConfig (tmpDir);
// Due to https://bugzilla.xamarin.com/show_bug.cgi?id=48311 we can get warnings related to the registrar
// So ignore anything with registrar.m or registrar.h or gl3.h in the line
Func<string, bool> hasLegitWarning = results =>
results.Split (Environment.NewLine.ToCharArray ()).Any (x => x.Contains ("warning") && !x.Contains ("registrar.m") && !x.Contains ("registrar.h") && !x.Contains ("gl3.h"));
results.Split (Environment.NewLine.ToCharArray ()).Any (x => x.Contains ("warning") && !x.Contains ("deviceBrowserView:selectionDidChange:"));
// Mobile
string buildResults = TI.TestUnifiedExecutable (test).BuildOutput;

Просмотреть файл

@ -711,6 +711,22 @@ class X : ReplayKit.RPBroadcastControllerDelegate
Verify (R.Static, code, true);
}
[Test]
public void NoWarnings ()
{
using (var mtouch = new MTouchTool ()) {
mtouch.CreateTemporaryApp ();
mtouch.CreateTemporaryCacheDirectory ();
mtouch.Registrar = MTouchRegistrar.Static;
mtouch.Linker = MTouchLinker.DontLink; // so that as much as possible is registered
mtouch.Verbosity = 9; // Increase verbosity, otherwise linker warnings aren't shown
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
mtouch.AssertNoWarnings ();
foreach (var line in mtouch.OutputLines)
Assert.That (line, Does.Not.Match ("warning:"), "no warnings");
}
}
[Test]
public void MultiplePropertiesInHierarchy ()
{

Просмотреть файл

@ -1206,6 +1206,12 @@ namespace XamCore.Registrar {
case "IsInformal":
rv.IsInformal = (bool) prop.Argument.Value;
break;
case "FormalSince":
Version version;
if (!Version.TryParse ((string)prop.Argument.Value, out version))
throw ErrorHelper.CreateError (4147, "Invalid {0} found on '{1}'. Please file a bug report at http://bugzilla.xamarin.com", "ProtocolAttribute", type.FullName);
rv.FormalSinceVersion = version;
break;
default:
throw ErrorHelper.CreateError (4147, "Invalid {0} found on '{1}'. Please file a bug report at http://bugzilla.xamarin.com", "ProtocolAttribute", type.FullName);
}
@ -3845,6 +3851,7 @@ namespace XamCore.Registrar {
public TypeDefinition WrapperType { get; set; }
public string Name { get; set; }
public bool IsInformal { get; set; }
public Version FormalSinceVersion { get; set; }
}
public sealed class ProtocolMemberAttribute : Attribute {