@@ -439,61 +439,26 @@ internal virtual void WriteField (Field field, string indent, GenBase type)
439439 public void WriteInterface ( InterfaceGen @interface , string indent , GenerationInfo gen_info )
440440 {
441441 opt . ContextTypes . Push ( @interface ) ;
442+
442443 // interfaces don't nest, so generate as siblings
443444 foreach ( GenBase nest in @interface . NestedTypes ) {
444445 WriteType ( nest , indent , gen_info ) ;
445446 writer . WriteLine ( ) ;
446447 }
447448
448- var staticMethods = @interface . Methods . Where ( m => m . IsStatic ) ;
449- if ( @interface . Fields . Any ( ) || staticMethods . Any ( ) ) {
450- string name = @interface . HasManagedName
451- ? @interface . Name . Substring ( 1 ) + "Consts"
452- : @interface . Name . Substring ( 1 ) ;
453- writer . WriteLine ( "{0}[Register (\" {1}\" {2}, DoNotGenerateAcw=true)]" , indent , @interface . RawJniName , @interface . AdditionalAttributeString ( ) ) ;
454- writer . WriteLine ( "{0}public abstract class {1} : Java.Lang.Object {{" , indent , name ) ;
455- writer . WriteLine ( ) ;
456- writer . WriteLine ( "{0}\t internal {1} ()" , indent , name ) ;
457- writer . WriteLine ( "{0}\t {{" , indent ) ;
458- writer . WriteLine ( "{0}\t }}" , indent ) ;
459-
460- var seen = new HashSet < string > ( ) ;
461- bool needsClassRef = WriteFields ( @interface . Fields , indent + "\t " , @interface , seen ) || staticMethods . Any ( ) ;
462- foreach ( var iface in @interface . GetAllImplementedInterfaces ( ) . OfType < InterfaceGen > ( ) ) {
463- writer . WriteLine ( ) ;
464- writer . WriteLine ( "{0}\t // The following are fields from: {1}" , indent , iface . JavaName ) ;
465- bool v = WriteFields ( iface . Fields , indent + "\t " , iface , seen ) ;
466- needsClassRef = needsClassRef || v ;
467- }
468-
469- foreach ( var m in @interface . Methods . Where ( m => m . IsStatic ) )
470- WriteMethod ( m , indent + "\t " , @interface , true ) ;
471-
472- if ( needsClassRef ) {
473- writer . WriteLine ( ) ;
474- WriteClassHandle ( @interface , indent + "\t " , name ) ;
475- }
449+ WriteInterfaceImplementedMembersAlternative ( @interface , indent ) ;
476450
477- writer . WriteLine ( "{0}}}" , indent , @interface . Name ) ;
478- writer . WriteLine ( ) ;
451+ // If this interface is just fields and we can't generate any of them
452+ // then we don't need to write the interface
453+ if ( @interface . IsConstSugar && @interface . GetGeneratableFields ( opt ) . Count ( ) == 0 )
454+ return ;
479455
480- if ( ! @interface . HasManagedName ) {
481- writer . WriteLine ( "{0}[Register (\" {1}\" {2}, DoNotGenerateAcw=true)]" , indent , @interface . RawJniName , @interface . AdditionalAttributeString ( ) ) ;
482- writer . WriteLine ( "{0}[global::System.Obsolete (\" Use the '{1}' type. This type will be removed in a future release.\" )]" , indent , name ) ;
483- writer . WriteLine ( "{0}public abstract class {1}Consts : {1} {{" , indent , name ) ;
484- writer . WriteLine ( ) ;
485- writer . WriteLine ( "{0}\t private {1}Consts ()" , indent , name ) ;
486- writer . WriteLine ( "{0}\t {{" , indent ) ;
487- writer . WriteLine ( "{0}\t }}" , indent ) ;
488- writer . WriteLine ( "{0}}}" , indent ) ;
489- writer . WriteLine ( ) ;
490- }
491- }
456+ WriteInterfaceDeclaration ( @interface , indent ) ;
492457
458+ // If this interface is just constant fields we don't need to write all the invoker bits
493459 if ( @interface . IsConstSugar )
494460 return ;
495461
496- WriteInterfaceDeclaration ( @interface , indent ) ;
497462 if ( ! @interface . AssemblyQualifiedName . Contains ( '/' ) )
498463 WriteInterfaceExtensionsDeclaration ( @interface , indent , null ) ;
499464 WriteInterfaceInvoker ( @interface , indent ) ;
@@ -545,11 +510,15 @@ public void WriteInterfaceDeclaration (InterfaceGen @interface, string indent)
545510
546511 if ( @interface . IsDeprecated )
547512 writer . WriteLine ( "{0}[ObsoleteAttribute (@\" {1}\" )]" , indent , @interface . DeprecatedComment ) ;
548- writer . WriteLine ( "{0}[Register (\" {1}\" , \" \" , \" {2}\" {3})]" , indent , @interface . RawJniName , @interface . Namespace + "." + @interface . FullName . Substring ( @interface . Namespace . Length + 1 ) . Replace ( '.' , '/' ) + "Invoker" , @interface . AdditionalAttributeString ( ) ) ;
513+
514+ if ( ! @interface . IsConstSugar )
515+ writer . WriteLine ( "{0}[Register (\" {1}\" , \" \" , \" {2}\" {3})]" , indent , @interface . RawJniName , @interface . Namespace + "." + @interface . FullName . Substring ( @interface . Namespace . Length + 1 ) . Replace ( '.' , '/' ) + "Invoker" , @interface . AdditionalAttributeString ( ) ) ;
516+
549517 if ( @interface . TypeParameters != null && @interface . TypeParameters . Any ( ) )
550518 writer . WriteLine ( "{0}{1}" , indent , @interface . TypeParameters . ToGeneratedAttributeString ( ) ) ;
551- writer . WriteLine ( "{0}{1} partial interface {2} : {3} {{" , indent , @interface . Visibility , @interface . Name ,
552- @interface . Interfaces . Count == 0 || sb . Length == 0 ? "IJavaObject" : sb . ToString ( ) ) ;
519+ writer . WriteLine ( "{0}{1} partial interface {2}{3} {{" , indent , @interface . Visibility , @interface . Name ,
520+ @interface . IsConstSugar ? string . Empty : @interface . Interfaces . Count == 0 || sb . Length == 0 ? " : IJavaObject" : " : " + sb . ToString ( ) ) ;
521+ WriteInterfaceFields ( @interface , indent + "\t " ) ;
553522 writer . WriteLine ( ) ;
554523 WriteInterfaceProperties ( @interface , indent + "\t " ) ;
555524 WriteInterfaceMethods ( @interface , indent + "\t " ) ;
@@ -707,6 +676,74 @@ public void WriteInterfaceExtensionsDeclaration (InterfaceGen @interface, string
707676 writer . WriteLine ( ) ;
708677 }
709678
679+ public void WriteInterfaceFields ( InterfaceGen iface , string indent )
680+ {
681+ // Interface fields are only supported with DIM
682+ if ( ! opt . SupportDefaultInterfaceMethods )
683+ return ;
684+
685+ var seen = new HashSet < string > ( ) ;
686+ var fields = iface . GetGeneratableFields ( opt ) . ToList ( ) ;
687+
688+ WriteFields ( fields , indent , iface , seen ) ;
689+ }
690+
691+ public void WriteInterfaceImplementedMembersAlternative ( InterfaceGen @interface , string indent )
692+ {
693+ // Historically .NET has not allowed interface implemented fields or constants, so we
694+ // initially worked around that by moving them to an abstract class, generally
695+ // IMyInterface -> MyInterfaceConsts
696+ // This was later expanded to accomodate static interface methods, creating a more appropriately named class
697+ // IMyInterface -> MyInterface
698+ // In this case the XXXConsts class is [Obsolete]'d and simply inherits from the newer class
699+ // in order to maintain backward compatibility.
700+ var staticMethods = @interface . Methods . Where ( m => m . IsStatic ) ;
701+
702+ if ( @interface . Fields . Any ( ) || staticMethods . Any ( ) ) {
703+ string name = @interface . HasManagedName
704+ ? @interface . Name . Substring ( 1 ) + "Consts"
705+ : @interface . Name . Substring ( 1 ) ;
706+ writer . WriteLine ( "{0}[Register (\" {1}\" {2}, DoNotGenerateAcw=true)]" , indent , @interface . RawJniName , @interface . AdditionalAttributeString ( ) ) ;
707+ writer . WriteLine ( "{0}public abstract class {1} : Java.Lang.Object {{" , indent , name ) ;
708+ writer . WriteLine ( ) ;
709+ writer . WriteLine ( "{0}\t internal {1} ()" , indent , name ) ;
710+ writer . WriteLine ( "{0}\t {{" , indent ) ;
711+ writer . WriteLine ( "{0}\t }}" , indent ) ;
712+
713+ var seen = new HashSet < string > ( ) ;
714+ bool needsClassRef = WriteFields ( @interface . Fields , indent + "\t " , @interface , seen ) || staticMethods . Any ( ) ;
715+ foreach ( var iface in @interface . GetAllImplementedInterfaces ( ) . OfType < InterfaceGen > ( ) ) {
716+ writer . WriteLine ( ) ;
717+ writer . WriteLine ( "{0}\t // The following are fields from: {1}" , indent , iface . JavaName ) ;
718+ bool v = WriteFields ( iface . Fields , indent + "\t " , iface , seen ) ;
719+ needsClassRef = needsClassRef || v ;
720+ }
721+
722+ foreach ( var m in @interface . Methods . Where ( m => m . IsStatic ) )
723+ WriteMethod ( m , indent + "\t " , @interface , true ) ;
724+
725+ if ( needsClassRef ) {
726+ writer . WriteLine ( ) ;
727+ WriteClassHandle ( @interface , indent + "\t " , name ) ;
728+ }
729+
730+ writer . WriteLine ( "{0}}}" , indent , @interface . Name ) ;
731+ writer . WriteLine ( ) ;
732+
733+ if ( ! @interface . HasManagedName ) {
734+ writer . WriteLine ( "{0}[Register (\" {1}\" {2}, DoNotGenerateAcw=true)]" , indent , @interface . RawJniName , @interface . AdditionalAttributeString ( ) ) ;
735+ writer . WriteLine ( "{0}[global::System.Obsolete (\" Use the '{1}' type. This type will be removed in a future release.\" )]" , indent , name ) ;
736+ writer . WriteLine ( "{0}public abstract class {1}Consts : {1} {{" , indent , name ) ;
737+ writer . WriteLine ( ) ;
738+ writer . WriteLine ( "{0}\t private {1}Consts ()" , indent , name ) ;
739+ writer . WriteLine ( "{0}\t {{" , indent ) ;
740+ writer . WriteLine ( "{0}\t }}" , indent ) ;
741+ writer . WriteLine ( "{0}}}" , indent ) ;
742+ writer . WriteLine ( ) ;
743+ }
744+ }
745+ }
746+
710747 public void WriteInterfaceInvoker ( InterfaceGen @interface , string indent )
711748 {
712749 writer . WriteLine ( "{0}[global::Android.Runtime.Register (\" {1}\" , DoNotGenerateAcw=true{2})]" , indent , @interface . RawJniName , @interface . AdditionalAttributeString ( ) ) ;
0 commit comments