99import  java .io .PrintStream ;
1010import  java .util .ArrayDeque ;
1111import  java .util .ArrayList ;
12+ import  java .util .Arrays ;
1213import  java .util .HashMap ;
1314import  java .util .HashSet ;
1415import  java .util .List ;
@@ -141,6 +142,9 @@ private Binding[] processRows(List<DataRow> rows) throws IOException {
141142            String  classname  = dataRow .getBaseClassname ();
142143            boolean  isJavaExtend  = classes .containsKey (classname );
143144            if  (isJavaExtend ) {
145+ 
146+ //                System.out.println("SBG: DataRow: baseClassName: " + classname + ", suffix: " + dataRow.getSuffix() + ", interfaces: " + String.join(", ", Arrays.asList(dataRow.getInterfaces())) + ", jsFileName: " + dataRow.getJsFilename()); 
147+ 
144148                Binding  binding  = generateBinding (dataRow , interfaceNames );
145149
146150                if  (binding  != null ) {
@@ -187,42 +191,56 @@ private String getNormalizedName(String filename) {
187191    private  Map <String , List <Method >> getPublicApi (JavaClass  clazz ) {
188192        Map <String , List <Method >> api  = new  HashMap <String , List <Method >>();
189193        JavaClass  currentClass  = clazz ;
194+         String  clazzName  = clazz .getClassName ();
190195        while  (true ) {
191196            String  currentClassname  = currentClass .getClassName ();
192-             List <Method > methods  = new  ArrayList <Method >();
193-             for  (Method  m  : currentClass .getMethods ()) {
194-                 methods .add (m );
195-             }
196-             collectInterfaceMethods (clazz , methods );
197-             for  (Method  m  : methods ) {
198-                 if  (!m .isSynthetic () && (m .isPublic () || m .isProtected ()) && !m .isStatic ()) {
199-                     String  name  = m .getName ();
200- 
201-                     List <Method > methodGroup ;
202-                     if  (api .containsKey (name )) {
203-                         methodGroup  = api .get (name );
204-                     } else  {
205-                         methodGroup  = new  ArrayList <Method >();
206-                         api .put (name , methodGroup );
207-                     }
208-                     boolean  found  = false ;
209-                     String  methodSig  = m .getSignature ();
210-                     for  (Method  m1  : methodGroup ) {
211-                         found  = methodSig .equals (m1 .getSignature ());
212-                         if  (found ) {
213-                             break ;
197+ 
198+             boolean  shouldCollectMethods  = !(!clazzName .equals (currentClassname ) && currentClass .isAbstract ());
199+ 
200+             if  (shouldCollectMethods  || currentClass .isInterface ()) {
201+                 // Don't include abstract parent class's methods to avoid compilation issues 
202+                 // where a child class has 2 methods, of the same type, with just a 
203+                 // return type/parameter type that differs by being of a superclass of the class being extended. 
204+                 // see Test testCanCompileBindingClassExtendingAnExtendedClassWithMethodsWithTheSameSignature 
205+                 List <Method > methods  = new  ArrayList <Method >();
206+                 for  (Method  m  : currentClass .getMethods ()) {
207+                     methods .add (m );
208+                 }
209+ 
210+ //                System.out.println("SBG: getPublicApi:collectInterfaceMethods classname: " + currentClassname); 
211+ 
212+                 collectInterfaceMethods (clazz , methods );
213+                 for  (Method  m  : methods ) {
214+                     if  (!m .isSynthetic () && (m .isPublic () || m .isProtected ()) && !m .isStatic ()) {
215+                         String  name  = m .getName ();
216+ 
217+                         List <Method > methodGroup ;
218+                         if  (api .containsKey (name )) {
219+                             methodGroup  = api .get (name );
220+                         } else  {
221+                             methodGroup  = new  ArrayList <Method >();
222+                             api .put (name , methodGroup );
223+                         }
224+                         boolean  found  = false ;
225+                         String  methodSig  = m .getSignature ();
226+                         for  (Method  m1  : methodGroup ) {
227+                             found  = methodSig .equals (m1 .getSignature ());
228+                             if  (found ) {
229+                                 break ;
230+                             }
231+                         }
232+                         if  (!found ) {
233+                             methodGroup .add (m );
214234                        }
215-                     }
216-                     if  (!found ) {
217-                         methodGroup .add (m );
218235                    }
219236                }
220237            }
221238
222239            if  (currentClassname .equals ("java.lang.Object" )) {
223240                break ;
224241            } else  {
225-                 currentClass  = classes .get (currentClass .getSuperclassName ());
242+                 String  superClassName  = currentClass .getSuperclassName ();
243+                 currentClass  = classes .get (superClassName .replace ('$' , '.' ));
226244            }
227245        }
228246        return  api ;
@@ -640,6 +658,7 @@ private void writeType(Type t, Writer w) {
640658
641659    private  void  collectInterfaceMethods (JavaClass  clazz , List <Method > methods ) {
642660        JavaClass  currentClass  = clazz ;
661+ 
643662        while  (true ) {
644663            String  currentClassname  = currentClass .getClassName ();
645664
@@ -663,7 +682,8 @@ private void collectInterfaceMethods(JavaClass clazz, List<Method> methods) {
663682            if  (currentClassname .equals ("java.lang.Object" )) {
664683                break ;
665684            } else  {
666-                 currentClass  = classes .get (currentClass .getSuperclassName ());
685+                 String  superClassName  = currentClass .getSuperclassName ();
686+                 currentClass  = classes .get (superClassName .replace ('$' , '.' ));
667687            }
668688        }
669689    }
@@ -686,7 +706,8 @@ private boolean isApplicationClass(JavaClass clazz, Map<String, JavaClass> class
686706                break ;
687707            }
688708
689-             currentClass  = classes .get (currentClass .getSuperclassName ());
709+             String  superClassName  = currentClass .getSuperclassName ();
710+             currentClass  = classes .get (superClassName .replace ('$' , '.' ));
690711        }
691712
692713        return  isApplicationClass ;
0 commit comments