Skip to content
Merged
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
7 changes: 7 additions & 0 deletions tests/generator-Tests/Unit-Tests/InterfaceConstantsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ protected override CodeGenerationOptions CreateOptions ()
[Test]
public void WriteConstSugarInterfaceFields ()
{
// Need a JLO class "FromXml" to trigger ConstSugar logic. (ie: this is "building" Mono.Android.dll)
var klass = new TestClass ("java.lang.Object", "java.lang.Object") {
FromXml = true,
};

options.SymbolTable.AddType (klass);

// This is an interface that only has fields (IsConstSugar)
// We treat a little differenly because they don't need to interop with Java
var iface = SupportTypeBuilder.CreateEmptyInterface ("java.code.IMyInterface");
Expand Down
2 changes: 2 additions & 0 deletions tools/generator/CodeGenerationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ internal CodeGenerator CreateCodeGenerator (TextWriter writer)
public bool SupportNestedInterfaceTypes { get; set; }
public bool SupportNullableReferenceTypes { get; set; }
public bool UseShallowReferencedTypes { get; set; }
public bool RemoveConstSugar => BuildingCoreAssembly;

bool? buildingCoreAssembly;
// Basically this means "Are we building Mono.Android.dll?"
public bool BuildingCoreAssembly {
get {
return buildingCoreAssembly ?? (buildingCoreAssembly = (SymbolTable.Lookup ("java.lang.Object") is ClassGen gen && gen.FromXml)).Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void WriteClass (ClassGen @class, string indent, GenerationInfo gen_info)
foreach (ISymbol isym in @class.Interfaces) {
GenericSymbol gs = isym as GenericSymbol;
InterfaceGen gen = (gs == null ? isym : gs.Gen) as InterfaceGen;
if (gen != null && (gen.IsConstSugar || gen.RawVisibility != "public"))
if (gen != null && (gen.IsConstSugar (opt) || gen.RawVisibility != "public"))
continue;
if (sb.Length > 0)
sb.Append (", ");
Expand Down Expand Up @@ -465,13 +465,13 @@ public void WriteInterface (InterfaceGen @interface, string indent, GenerationIn

// If this interface is just fields and we can't generate any of them
// then we don't need to write the interface
if (@interface.IsConstSugar && @interface.GetGeneratableFields (opt).Count () == 0)
if (@interface.IsConstSugar (opt) && @interface.GetGeneratableFields (opt).Count () == 0)
return;

WriteInterfaceDeclaration (@interface, indent, gen_info);

// If this interface is just constant fields we don't need to write all the invoker bits
if (@interface.IsConstSugar)
if (@interface.IsConstSugar (opt))
return;

if (!@interface.AssemblyQualifiedName.Contains ('/'))
Expand Down Expand Up @@ -514,7 +514,7 @@ public void WriteInterfaceDeclaration (InterfaceGen @interface, string indent, G
StringBuilder sb = new StringBuilder ();
foreach (ISymbol isym in @interface.Interfaces) {
InterfaceGen igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen;
if (igen.IsConstSugar || igen.RawVisibility != "public")
if (igen.IsConstSugar (opt) || igen.RawVisibility != "public")
continue;
if (sb.Length > 0)
sb.Append (", ");
Expand All @@ -526,7 +526,7 @@ public void WriteInterfaceDeclaration (InterfaceGen @interface, string indent, G
if (@interface.IsDeprecated)
writer.WriteLine ("{0}[ObsoleteAttribute (@\"{1}\")]", indent, @interface.DeprecatedComment);

if (!@interface.IsConstSugar) {
if (!@interface.IsConstSugar (opt)) {
var signature = string.IsNullOrWhiteSpace (@interface.Namespace)
? @interface.FullName.Replace ('.', '/')
: @interface.Namespace + "." + @interface.FullName.Substring (@interface.Namespace.Length + 1).Replace ('.', '/');
Expand All @@ -537,7 +537,7 @@ public void WriteInterfaceDeclaration (InterfaceGen @interface, string indent, G
if (@interface.TypeParameters != null && @interface.TypeParameters.Any ())
writer.WriteLine ("{0}{1}", indent, @interface.TypeParameters.ToGeneratedAttributeString ());
writer.WriteLine ("{0}{1} partial interface {2}{3} {{", indent, @interface.Visibility, @interface.Name,
@interface.IsConstSugar ? string.Empty : @interface.Interfaces.Count == 0 || sb.Length == 0 ? " : " + GetAllInterfaceImplements () : " : " + sb.ToString ());
@interface.IsConstSugar (opt) ? string.Empty : @interface.Interfaces.Count == 0 || sb.Length == 0 ? " : " + GetAllInterfaceImplements () : " : " + sb.ToString ());

if (opt.SupportDefaultInterfaceMethods && (@interface.HasDefaultMethods || @interface.HasStaticMethods))
WriteClassHandle (@interface, indent + "\t", @interface.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,24 @@ public IEnumerable<Field> GetGeneratableFields (CodeGenerationOptions options)

public bool HasStaticMethods => GetAllMethods ().Any (m => m.IsStatic);

public bool IsConstSugar {
get {
if (Methods.Count > 0 || Properties.Count > 0)
return false;
public bool IsConstSugar (CodeGenerationOptions options)
{
if (!options.RemoveConstSugar)
return false;

foreach (InterfaceGen impl in GetAllDerivedInterfaces ())
if (!impl.IsConstSugar)
return false;
if (Methods.Count > 0 || Properties.Count > 0)
return false;

// Need to keep Java.IO.ISerializable as a "marker interface"; want to
// hide android.provider.ContactsContract.DataColumnsWithJoins
if (Fields.Count == 0 && Interfaces.Count == 0)
foreach (InterfaceGen impl in GetAllDerivedInterfaces ())
if (!impl.IsConstSugar (options))
return false;

return true;
}
// Need to keep Java.IO.ISerializable as a "marker interface"; want to
// hide android.provider.ContactsContract.DataColumnsWithJoins
if (Fields.Count == 0 && Interfaces.Count == 0)
return false;

return true;
}

// If there is a property it cannot generate valid implementor, so reject this at least so far.
Expand Down
2 changes: 1 addition & 1 deletion tools/generator/SourceWriters/BoundClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void AddCharSequenceEnumerator (ClassGen klass)
void AddImplementedInterfaces (ClassGen klass)
{
foreach (var isym in klass.Interfaces) {
if ((!(isym is GenericSymbol gs) ? isym : gs.Gen) is InterfaceGen gen && (gen.IsConstSugar || gen.RawVisibility != "public"))
if ((!(isym is GenericSymbol gs) ? isym : gs.Gen) is InterfaceGen gen && (gen.IsConstSugar (opt) || gen.RawVisibility != "public"))
continue;

Implements.Add (opt.GetOutputName (isym.FullName));
Expand Down
10 changes: 5 additions & 5 deletions tools/generator/SourceWriters/BoundInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public BoundInterface (InterfaceGen iface, CodeGenerationOptions opt, CodeGenera
// If this interface is just fields and we can't generate any of them
// then we don't need to write the interface. We still keep this type
// because it may have nested types or need an InterfaceMemberAlternativeClass.
if (iface.IsConstSugar && iface.GetGeneratableFields (opt).Count () == 0) {
if (iface.IsConstSugar (opt) && iface.GetGeneratableFields (opt).Count () == 0) {
dont_generate = true;
return;
}
Expand All @@ -43,7 +43,7 @@ public BoundInterface (InterfaceGen iface, CodeGenerationOptions opt, CodeGenera
if (iface.IsDeprecated)
Attributes.Add (new ObsoleteAttr (iface.DeprecatedComment) { WriteAttributeSuffix = true, WriteEmptyString = true });

if (!iface.IsConstSugar) {
if (!iface.IsConstSugar (opt)) {
var signature = string.IsNullOrWhiteSpace (iface.Namespace)
? iface.FullName.Replace ('.', '/')
: iface.Namespace + "." + iface.FullName.Substring (iface.Namespace.Length + 1).Replace ('.', '/');
Expand All @@ -63,7 +63,7 @@ public BoundInterface (InterfaceGen iface, CodeGenerationOptions opt, CodeGenera
AddNestedTypes (iface, opt, context, genInfo);

// If this interface is just constant fields we don't need to add all the invoker bits
if (iface.IsConstSugar)
if (iface.IsConstSugar (opt))
return;

if (!iface.AssemblyQualifiedName.Contains ('/')) {
Expand Down Expand Up @@ -137,13 +137,13 @@ void AddInheritedInterfaces (InterfaceGen iface, CodeGenerationOptions opt)
foreach (var isym in iface.Interfaces) {
var igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen;

if (igen.IsConstSugar || igen.RawVisibility != "public")
if (igen.IsConstSugar (opt) || igen.RawVisibility != "public")
continue;

Implements.Add (opt.GetOutputName (isym.FullName));
}

if (Implements.Count == 0 && !iface.IsConstSugar)
if (Implements.Count == 0 && !iface.IsConstSugar (opt))
Implements.AddRange (new [] { "IJavaObject", "IJavaPeerable" });
}

Expand Down