Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@

This can be opted into locally with $(_AndroidTreatWarningsAsErrors) = true.
-->
<_AllowProjectWarnings Condition=" '$(MSBuildProjectFile)' == 'Mono.Android.csproj' ">true</_AllowProjectWarnings>
<_AllowProjectWarnings Condition=" '$(MSBuildProjectFile)' == 'Mono.Android.NET-Tests.csproj' ">true</_AllowProjectWarnings>
<_AllowProjectWarnings Condition=" '$(MSBuildProjectFile)' == 'NativeAOT.csproj' ">true</_AllowProjectWarnings>
<_AllowProjectWarnings Condition=" '$(MSBuildProjectFile)' == 'TestRunner.Core.NET.csproj' ">true</_AllowProjectWarnings>
Expand Down
4 changes: 3 additions & 1 deletion build-tools/jnienv-gen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static void GenerateFile (TextWriter o)
o.WriteLine ("//");
o.WriteLine ("// To make changes, edit monodroid/tools/jnienv-gen and rerun");
o.WriteLine ();
o.WriteLine ("#nullable enable");
o.WriteLine ();
o.WriteLine ("using System;");
o.WriteLine ("using System.Runtime.ExceptionServices;");
o.WriteLine ("using System.Runtime.InteropServices;");
Expand Down Expand Up @@ -199,7 +201,7 @@ static void GenerateJniEnv (TextWriter o)
var copyArray = JNIEnvEntries.Single (e => e.Name.StartsWith ("Get", StringComparison.Ordinal) && e.Name.EndsWith ("ArrayRegion", StringComparison.Ordinal) &&
e.Parameters [0].Type.Type == entry.ReturnType.Type);
o.Write ("\t\t{2} static {0} {1} (", entry.ReturnType.ManagedType, entry.ApiName, entry.Visibility);
o.WriteLine ("{0} array)", copyArray.Parameters [3].Type.ManagedType);
o.WriteLine ("{0}? array)", copyArray.Parameters [3].Type.ManagedType);
o.WriteLine ("\t\t{");
o.WriteLine ("\t\t\tif (array == null)");
o.WriteLine ("\t\t\t\treturn IntPtr.Zero;");
Expand Down
4 changes: 2 additions & 2 deletions build-tools/scripts/JavaCallableWrappers.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="GenerateJavaCallableWrappers"
AfterTargets="$(JavaCallableWrapperAfterTargets)"
Inputs="$(JavaCallableWrapperAbsAssembly);@(JavaCallableWrapperSource)"
Inputs="$(MSBuildThisFileFullPath);$(JavaCallableWrapperAbsAssembly);@(JavaCallableWrapperSource)"
Outputs="$(OutputPath)mono.android.jar">
<MakeDir Directories="$(IntermediateOutputPath)jcw;$(IntermediateOutputPath)jcw/bin" />
<ItemGroup>
Expand All @@ -29,7 +29,7 @@
Overwrite="True"
/>
<PropertyGroup>
<_Target>-source $(JavacSourceVersion) -target $(JavacTargetVersion)</_Target>
<_Target>--release $(JavacTargetVersion)</_Target>
Comment thread
simonrozsival marked this conversation as resolved.
<_D>-d "$(IntermediateOutputPath)jcw/bin"</_D>
<_AndroidJar>"$(AndroidSdkDirectory)\platforms\android-$(AndroidPlatformId)\android.jar"</_AndroidJar>
<_MonoAndroidJar>$(OutputPath)mono.android.jar</_MonoAndroidJar>
Expand Down
33 changes: 33 additions & 0 deletions external/Java.Interop/src/Xamarin.SourceWriter/CodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class CodeWriter : IDisposable
int indent;
bool need_indent = true;
string base_indent;
readonly Dictionary<string, int> suppression_depth = new Dictionary<string, int> ();

public CodeWriter (string filename)
{
Expand All @@ -31,6 +32,38 @@ public void Write (string value)
stream.Write (value);
}

// `#pragma warning restore` ends a suppression however many `disable` directives
// preceded it, so a nested `disable`/`restore` pair for the same code would stop
// suppressing the enclosing scope early. Track how deep each code is nested and let
// only the outermost pair be written.
public bool BeginWarningSuppression (string code)
{
if (code == null)
throw new ArgumentNullException (nameof (code));

suppression_depth.TryGetValue (code, out var depth);
suppression_depth [code] = depth + 1;

return depth == 0;
}

public bool EndWarningSuppression (string code)
{
if (code == null)
throw new ArgumentNullException (nameof (code));

if (!suppression_depth.TryGetValue (code, out var depth) || depth == 0)
throw new InvalidOperationException ($"No warning suppression is open for '{code}'.");

suppression_depth [code] = depth - 1;

return depth == 1;
}

public bool IsWarningSuppressed (string code) =>
suppression_depth.TryGetValue (code, out var depth) && depth > 0;


public void WriteLine ()
{
stream.WriteLine ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

namespace Xamarin.SourceWriter
{
public class EventWriter : ISourceWriter
public class EventWriter : ISourceWriter, ISuppressWarnings
{
Visibility visibility;

public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();
public string Name { get; set; }
public TypeReferenceWriter EventType { get; set; }
public List<string> Comments { get; } = new List<string> ();
Expand Down Expand Up @@ -54,9 +55,11 @@ public void SetVisibility (string visibility)

public virtual void Write (CodeWriter writer)
{
this.WriteSuppressWarningsStart (writer);
WriteComments (writer);
WriteAttributes (writer);
WriteSignature (writer);
this.WriteSuppressWarningsEnd (writer);
}

public virtual void WriteComments (CodeWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

namespace Xamarin.SourceWriter
{
public class FieldWriter : ISourceWriter
public class FieldWriter : ISourceWriter, ISuppressWarnings
{
Visibility visibility;

public string Name { get; set; }
public TypeReferenceWriter Type { get; set; }
public List<string> Comments { get; } = new List<string> ();
public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();
public List<AttributeWriter> Attributes { get; } = new List<AttributeWriter> ();
public bool IsPublic { get => visibility.HasFlag (Visibility.Public); set => visibility = value ? Visibility.Public : Visibility.Default; }
public bool UseExplicitPrivateKeyword { get; set; }
Expand Down Expand Up @@ -47,9 +48,11 @@ public void SetVisibility (string visibility)

public virtual void Write (CodeWriter writer)
{
this.WriteSuppressWarningsStart (writer);
WriteComments (writer);
WriteAttributes (writer);
WriteSignature (writer);
this.WriteSuppressWarningsEnd (writer);
}

public virtual void WriteComments (CodeWriter writer)
Expand All @@ -75,16 +78,17 @@ public virtual void WriteSignature (CodeWriter writer)
else if (IsPrivate)
writer.Write ("private ");

// `new` must precede `const`, so write it first for all field kinds.
if (IsShadow)
writer.Write ("new ");

if (IsStatic)
writer.Write ("static ");
if (IsReadonly)
writer.Write ("readonly ");
if (IsConst)
writer.Write ("const ");

if (IsShadow)
writer.Write ("new ");

WriteType (writer);

if (Value.HasValue ()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace Xamarin.SourceWriter
{
public class MethodWriter : ISourceWriter, ITakeParameters
public class MethodWriter : ISourceWriter, ITakeParameters, ISuppressWarnings
{
Visibility visibility;

public string Name { get; set; }
public List<MethodParameterWriter> Parameters { get; } = new List<MethodParameterWriter> ();
public TypeReferenceWriter ReturnType { get; set; }
public List<string> Comments { get; } = new List<string> ();
public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();
public List<AttributeWriter> Attributes { get; } = new List<AttributeWriter> ();
public bool IsPublic { get => visibility == Visibility.Public; set => visibility = value ? Visibility.Public : Visibility.Default; }
public bool UseExplicitPrivateKeyword { get; set; }
Expand Down Expand Up @@ -53,9 +54,11 @@ public void SetVisibility (string visibility)

public virtual void Write (CodeWriter writer)
{
this.WriteSuppressWarningsStart (writer);
WriteComments (writer);
WriteAttributes (writer);
WriteSignature (writer);
this.WriteSuppressWarningsEnd (writer);
}

public virtual void WriteComments (CodeWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace Xamarin.SourceWriter
{
public class PropertyWriter : ISourceWriter
public class PropertyWriter : ISourceWriter, ISuppressWarnings
{
Visibility visibility;

public string Name { get; set; }
public List<MethodParameterWriter> Parameters { get; } = new List<MethodParameterWriter> ();
public TypeReferenceWriter PropertyType { get; set; }
public List<string> Comments { get; } = new List<string> ();
public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();
public List<AttributeWriter> Attributes { get; } = new List<AttributeWriter> ();
public bool IsPublic { get => visibility.HasFlag (Visibility.Public); set => visibility |= Visibility.Public; }
public bool UseExplicitPrivateKeyword { get; set; }
Expand Down Expand Up @@ -57,9 +58,11 @@ public void SetVisibility (string visibility)

public virtual void Write (CodeWriter writer)
{
this.WriteSuppressWarningsStart (writer);
WriteComments (writer);
WriteAttributes (writer);
WriteSignature (writer);
this.WriteSuppressWarningsEnd (writer);
}

public virtual void WriteComments (CodeWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Xamarin.SourceWriter
{
public abstract class TypeWriter : ISourceWriter
public abstract class TypeWriter : ISourceWriter, ISuppressWarnings
{
Visibility visibility;
int current_priority = 1;
Expand All @@ -24,6 +24,11 @@ public abstract class TypeWriter : ISourceWriter
public bool IsProtected { get => visibility.HasFlag (Visibility.Protected); set => visibility = value ? Visibility.Protected : Visibility.Default; }
public ObservableCollection<MethodWriter> Methods { get; } = new ObservableCollection<MethodWriter> ();
public List<string> Comments { get; } = new List<string> ();
public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();

// Suppressions that only have to cover the type's declaration -- its base list, for
// example -- rather than everything the type contains.
public WarningSuppressionScope SignatureSuppressions { get; } = new WarningSuppressionScope ();
public List<AttributeWriter> Attributes { get; } = new List<AttributeWriter> ();
public ObservableCollection<EventWriter> Events { get; } = new ObservableCollection<EventWriter> ();
public ObservableCollection<FieldWriter> Fields { get; } = new ObservableCollection<FieldWriter> ();
Expand Down Expand Up @@ -77,11 +82,15 @@ public void SetVisibility (string visibility)

public virtual void Write (CodeWriter writer)
{
this.WriteSuppressWarningsStart (writer);
WriteComments (writer);
WriteAttributes (writer);
SignatureSuppressions.WriteSuppressWarningsStart (writer);
WriteSignature (writer);
SignatureSuppressions.WriteSuppressWarningsEnd (writer);
WriteMembers (writer);
WriteTypeClose (writer);
this.WriteSuppressWarningsEnd (writer);
}

public virtual void WriteComments (CodeWriter writer)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Xamarin.SourceWriter
{
// A single compiler diagnostic that has to be suppressed around one generated member,
// together with the reason it cannot be avoided. Suppressions are deliberately scoped to
// the member that needs them so that the same diagnostic elsewhere still breaks the build.
public class WarningSuppression
{
public string Code { get; }
public string Reason { get; }

public WarningSuppression (string code, string reason)
{
Code = code ?? throw new ArgumentNullException (nameof (code));
Reason = reason ?? throw new ArgumentNullException (nameof (reason));
}
}

// Implemented by the writers that can emit a member-scoped `#pragma warning disable`.
public interface ISuppressWarnings
{
List<WarningSuppression> SuppressWarnings { get; }
}

// A standalone set of suppressions, for the generated constructs that are written
// directly to a `CodeWriter` instead of through a writer that implements
// `ISuppressWarnings`.
public class WarningSuppressionScope : ISuppressWarnings
{
public List<WarningSuppression> SuppressWarnings { get; } = new List<WarningSuppression> ();
}

public static class WarningSuppressionExtensions
{
public static void WriteSuppressWarningsStart (this ISuppressWarnings self, CodeWriter writer)
{
foreach (var suppression in Ordered (self)) {
// The writer tracks how deeply each code is nested, so a member inside an
// already-suppressed scope does not emit a redundant pair that would end the
// enclosing suppression when it is restored.
if (!writer.BeginWarningSuppression (suppression.Code))
continue;

writer.WriteLine ($"// {suppression.Reason}");
writer.WriteLine ($"#pragma warning disable {suppression.Code}");
}
}

public static void WriteSuppressWarningsEnd (this ISuppressWarnings self, CodeWriter writer)
{
foreach (var suppression in Ordered (self).Reverse ()) {
if (!writer.EndWarningSuppression (suppression.Code))
continue;

writer.WriteLine ($"#pragma warning restore {suppression.Code}");
}
}

// The same diagnostic can be reported for more than one reason on a single member,
// so each code is emitted once, with the reasons combined.
static IList<WarningSuppression> Ordered (ISuppressWarnings self) =>
self.SuppressWarnings
.GroupBy (s => s.Code)
.OrderBy (g => g.Key, StringComparer.Ordinal)
.Select (g => g.Count () == 1
? g.First ()
: new WarningSuppression (g.Key, string.Join (" ", g.Select (s => s.Reason).Distinct ())))
.ToList ();
}
}
Loading
Loading