Skip to content

Commit 24f8084

Browse files
authored
[generator] Emit new when hiding Handle, Message (#49)
The internal Xamarin.Android CI system is reporting an error when running the `generator` unit tests, but it's a false positive. It's *not* a bug in `generator`. Rather, it's a bug in Mono 4.2, in which [`CSharpCodeCompiler` treats multi-line warnings as errors][0]. Since the `generator` unit tests emit such multi-line warnings when hiding `Java.Lang.Object.Handle` (via `Xamarin.Test.SomeObject.Handle()`) and `System.Exception.Message` (via `Java.Lang.Throwable.Message`), and Mono 4.2 treats the multi-line warnings as errors, the tests fail. There are three plausible solutions so that we don't get erroneous reports from the `generator` tests when running on Mono 4.2: 1. Remove those tests. (Uh...no.) 2. Upgrade Mono on the CI machine to Mono 4.4, which has the fix. 3. Fix `generator` so that the warning isn't emitted. (2) would require an unknown timeframe with unknown repercussions. Thus, the chosen fix: improve `generator` so that the warning isn't generated. [0]: mono/mono#2248
1 parent 04f9e3e commit 24f8084

File tree

8 files changed

+46
-13
lines changed

8 files changed

+46
-13
lines changed

tools/generator/GenBase.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,30 @@ public string MetadataXPathReference {
178178
public string GetObjectHandleProperty (string variable)
179179
{
180180
var handleType = "Java.Lang.Object";
181-
if (FullName == "Java.Lang.Throwable" || Ancestors ().Any (a => a.FullName == "Java.Lang.Throwable"))
181+
if (IsThrowable ())
182182
handleType = "Java.Lang.Throwable";
183183

184184
return $"((global::{handleType}) {variable}).Handle";
185185
}
186186

187+
bool IsThrowable ()
188+
{
189+
if (FullName == "Java.Lang.Throwable" || Ancestors ().Any (a => a.FullName == "Java.Lang.Throwable"))
190+
return true;
191+
return false;
192+
}
193+
194+
public bool RequiresNew (string memberName)
195+
{
196+
if (Array.BinarySearch (ObjectRequiresNew, memberName, StringComparer.OrdinalIgnoreCase) >= 0) {
197+
return true;
198+
}
199+
if (IsThrowable () && Array.BinarySearch (ThrowableRequiresNew, memberName, StringComparer.OrdinalIgnoreCase) >= 0) {
200+
return true;
201+
}
202+
return false;
203+
}
204+
187205
protected IEnumerable<InterfaceGen> GetAllImplementedInterfaces ()
188206
{
189207
var set = new HashSet<InterfaceGen> ();
@@ -508,15 +526,19 @@ bool CanMethodBeIsStyleSetter (Method m)
508526
}
509527

510528
// Keep sorted alphabetically
511-
static readonly string[] blacklist = new string[]{
529+
static readonly string[] ObjectRequiresNew = new string[]{
512530
"Handle",
513531
};
514532

533+
static readonly string[] ThrowableRequiresNew = new string []{
534+
"Message",
535+
};
536+
515537
bool IsInfrastructural (string name)
516538
{
517539
// some names are reserved for use by us, e.g. we don't want another
518540
// Handle property, as that conflicts with Java.Lang.Object.Handle.
519-
return Array.BinarySearch (blacklist, name) >= 0;
541+
return Array.BinarySearch (ObjectRequiresNew, name) >= 0;
520542
}
521543

522544
protected void GenCharSequenceEnumerator (StreamWriter sw, string indent, CodeGenerationOptions opt)

tools/generator/Method.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,9 @@ public void Generate (StreamWriter sw, string indent, CodeGenerationOptions opt,
799799

800800
string static_arg = IsStatic ? " static" : String.Empty;
801801
string virt_ov = IsOverride ? " override" : IsVirtual ? " virtual" : String.Empty;
802+
if ((string.IsNullOrEmpty (virt_ov) || virt_ov == " virtual") && type.RequiresNew (AdjustedName)) {
803+
virt_ov = " new" + virt_ov;
804+
}
802805
string seal = IsOverride && IsFinal ? " sealed" : null;
803806
string ret = opt.GetOutputName (RetVal.FullName);
804807
GenerateIdField (sw, indent, opt);

tools/generator/Property.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,17 @@ public void GenerateAbstractDeclaration (StreamWriter sw, string indent, CodeGen
6565
overrides = true;
6666
}
6767

68+
bool requiresNew = false;
6869
string abstract_name = AdjustedName;
6970
string visibility = Getter.RetVal.IsGeneric ? "protected" : Getter.Visibility;
70-
if (!overrides)
71+
if (!overrides) {
72+
requiresNew = gen.RequiresNew (abstract_name);
7173
GenerateCallbacks (sw, indent, opt, gen, abstract_name);
72-
sw.WriteLine ("{0}{1} abstract{2} {3} {4} {{",
74+
}
75+
sw.WriteLine ("{0}{1}{2} abstract{3} {4} {5} {{",
7376
indent,
7477
visibility,
78+
requiresNew ? " new" : "",
7579
overrides ? " override" : "",
7680
opt.GetOutputName (Getter.ReturnType),
7781
abstract_name);
@@ -199,22 +203,23 @@ public void Generate (GenBase gen, StreamWriter sw, string indent, CodeGeneratio
199203
force_override = true;
200204

201205
string decl_name = AdjustedName;
206+
string needNew = gen.RequiresNew (decl_name) ? " new" : "";
202207
string virtual_override = String.Empty;
203208
bool is_virtual = Getter.IsVirtual && (Setter == null || Setter.IsVirtual);
204209
if (with_callbacks && is_virtual) {
205-
virtual_override = " virtual";
210+
virtual_override = needNew + " virtual";
206211
Getter.GenerateCallback (sw, indent, opt, gen, AdjustedName);
207212
}
208213
if (with_callbacks && is_virtual && Setter != null) {
209-
virtual_override = " virtual";
214+
virtual_override = needNew + " virtual";
210215
Setter.GenerateCallback (sw, indent, opt, gen, AdjustedName);
211216
}
212217
virtual_override = force_override ? " override" : virtual_override;
213218
if ((Getter ?? Setter).IsStatic)
214219
virtual_override = " static";
215220
// It should be using AdjustedName instead of Name, but ICharSequence ("Formatted") properties are not caught by this...
216221
else if (gen.BaseSymbol != null && gen.BaseSymbol.GetPropertyByName (Name, true) != null)
217-
virtual_override = " override";
222+
virtual_override = needNew + " override";
218223

219224
Getter.GenerateIdField (sw, indent, opt);
220225
if (Setter != null)

tools/generator/Tests/BaseGeneratorTest.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ protected void CompareOutputs (string sourceDir, string destinationDir)
5757
if (!File.Exists (dest)) {
5858
Assert.Fail (string.Format ("Expected {0} but it was not generated.", dest));
5959
} else if (!FileCompare (file, dest)) {
60-
Assert.Fail (string.Format ("The Files {0} and {1} do not match", file, dest));
60+
var fullSource = Path.GetFullPath (file);
61+
var fullDest = Path.GetFullPath (dest);
62+
string message = $"File contents differ; run: diff -u {fullSource} \\{Environment.NewLine}\t{fullDest}";
63+
Assert.Fail (message);
6164
}
6265
}
6366
}

tools/generator/Tests/expected.ji/NormalMethods/Xamarin.Test.SomeObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ static int n_Handle_Ljava_lang_Object_Ljava_lang_Throwable_ (IntPtr jnienv, IntP
7171

7272
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/method[@name='handle' and count(parameter)=2 and parameter[1][@type='java.lang.Object'] and parameter[2][@type='java.lang.Throwable']]"
7373
[Register ("handle", "(Ljava/lang/Object;Ljava/lang/Throwable;)I", "GetHandle_Ljava_lang_Object_Ljava_lang_Throwable_Handler")]
74-
public virtual unsafe int Handle (global::Java.Lang.Object o, global::Java.Lang.Throwable t)
74+
public new virtual unsafe int Handle (global::Java.Lang.Object o, global::Java.Lang.Throwable t)
7575
{
7676
const string __id = "handle.(Ljava/lang/Object;Ljava/lang/Throwable;)I";
7777
try {

tools/generator/Tests/expected.ji/Streams/Java.Lang.Throwable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static IntPtr n_GetMessage (IntPtr jnienv, IntPtr native__this)
3232
}
3333
#pragma warning restore 0169
3434

35-
public virtual unsafe string Message {
35+
public new virtual unsafe string Message {
3636
// Metadata.xml XPath method reference: path="/api/package[@name='java.lang']/class[@name='Throwable']/method[@name='getMessage' and count(parameter)=0]"
3737
[Register ("getMessage", "()Ljava/lang/String;", "GetGetMessageHandler")]
3838
get {

tools/generator/Tests/expected/NormalMethods/Xamarin.Test.SomeObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static int n_Handle_Ljava_lang_Object_Ljava_lang_Throwable_ (IntPtr jnienv, IntP
7777
static IntPtr id_handle_Ljava_lang_Object_Ljava_lang_Throwable_;
7878
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/class[@name='SomeObject']/method[@name='handle' and count(parameter)=2 and parameter[1][@type='java.lang.Object'] and parameter[2][@type='java.lang.Throwable']]"
7979
[Register ("handle", "(Ljava/lang/Object;Ljava/lang/Throwable;)I", "GetHandle_Ljava_lang_Object_Ljava_lang_Throwable_Handler")]
80-
public virtual unsafe int Handle (global::Java.Lang.Object o, global::Java.Lang.Throwable t)
80+
public new virtual unsafe int Handle (global::Java.Lang.Object o, global::Java.Lang.Throwable t)
8181
{
8282
if (id_handle_Ljava_lang_Object_Ljava_lang_Throwable_ == IntPtr.Zero)
8383
id_handle_Ljava_lang_Object_Ljava_lang_Throwable_ = JNIEnv.GetMethodID (class_ref, "handle", "(Ljava/lang/Object;Ljava/lang/Throwable;)I");

tools/generator/Tests/expected/Streams/Java.Lang.Throwable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static IntPtr n_GetMessage (IntPtr jnienv, IntPtr native__this)
3232
#pragma warning restore 0169
3333

3434
static IntPtr id_getMessage;
35-
public virtual unsafe string Message {
35+
public new virtual unsafe string Message {
3636
// Metadata.xml XPath method reference: path="/api/package[@name='java.lang']/class[@name='Throwable']/method[@name='getMessage' and count(parameter)=0]"
3737
[Register ("getMessage", "()Ljava/lang/String;", "GetGetMessageHandler")]
3838
get {

0 commit comments

Comments
 (0)