88import org .apache .bcel .generic .BasicType ;
99import org .apache .bcel .generic .ObjectType ;
1010import org .apache .bcel .generic .Type ;
11+ import org .apache .bcel .util .BCELComparator ;
1112
1213import java .util .ArrayList ;
1314import java .util .Arrays ;
1415import java .util .HashMap ;
1516import java .util .HashSet ;
17+ import java .util .LinkedList ;
1618import java .util .List ;
1719import java .util .Map ;
20+ import java .util .Queue ;
1821import java .util .Set ;
1922
2023/**
@@ -34,6 +37,8 @@ public class DtsApi {
3437
3538 public DtsApi () {
3639 this .indent = 0 ;
40+
41+ overrideFieldComparator ();
3742 }
3843
3944 public String generateDtsContent (List <JavaClass > javaClasses ) {
@@ -49,6 +54,7 @@ public String generateDtsContent(List<JavaClass> javaClasses) {
4954
5055 JavaClass currClass = javaClasses .get (i );
5156 currentFileClassname = currClass .getClassName ();
57+ boolean isInterface = currClass .isInterface ();
5258
5359 this .indent = closePackage (this .prevClass , currClass );
5460 this .indent = openPackage (this .prevClass , currClass );
@@ -65,19 +71,35 @@ public String generateDtsContent(List<JavaClass> javaClasses) {
6571 sbContent .appendln (tabs + "export class " + getSimpleClassname (currClass ) + extendsLine + " {" );
6672 }
6773 // process member scope
68- List <FieldOrMethod > foms = getMembers (currClass );
69- for (FieldOrMethod fom : foms ) {
70- if (fom instanceof Field ) {
71- processField ((Field )fom , currClass );
74+
75+ // process constructors for interfaces
76+ if (isInterface ) {
77+ List <JavaClass > allInterfaces = getAllInterfaces (currClass );
78+
79+ List <Method > allInterfacesMethods = getAllInterfacesMethods (allInterfaces );
80+ Set <Field > allInterfaceFields = getAllInterfacesFields (allInterfaces );
81+ processInterfaceConstructor (currClass , allInterfacesMethods );
82+
83+ for (Method m : allInterfacesMethods ) {
84+ processMethod (m , currClass );
7285 }
73- else if (fom instanceof Method ) {
74- processMethod ((Method )fom , currClass );
86+
87+ for (Field f : allInterfaceFields ) {
88+ processField (f , currClass );
7589 }
76- else {
77- throw new IllegalArgumentException ("Argument is not method or field" );
90+ } else {
91+ List <FieldOrMethod > foms = getMembers (currClass );
92+ for (FieldOrMethod fom : foms ) {
93+ if (fom instanceof Field ) {
94+ processField ((Field ) fom , currClass );
95+ } else if (fom instanceof Method ) {
96+ processMethod ((Method ) fom , currClass );
97+ } else {
98+ throw new IllegalArgumentException ("Argument is not method or field" );
99+ }
78100 }
101+ // process member scope end
79102 }
80- // process member scope end
81103
82104 sbContent .appendln (tabs + "}" );
83105 if (getSimpleClassname (currClass ).equals ("AccessibilityDelegate" )) {
@@ -207,6 +229,79 @@ private int openPackage(JavaClass prevClass, JavaClass currClass) {
207229 return indent ;
208230 }
209231
232+ private void processInterfaceConstructor (JavaClass classInterface , List <Method > allInterfacesMethods ) {
233+ String tabs = getTabs (this .indent + 1 );
234+
235+ generateInterfaceConstructorContent (classInterface , tabs , allInterfacesMethods );
236+ }
237+
238+ private void generateInterfaceConstructorContent (JavaClass classInterface , String tabs , List <Method > methods ) {
239+ generateInterfaceConstructorCommentBlock (classInterface , tabs );
240+
241+ sbContent .appendln (tabs + "public constructor(implementation: {" );
242+
243+ for (Method m : methods ) {
244+ sbContent .append (getTabs (this .indent + 2 ) + getMethodName (m ) + getMethodParamSignature (classInterface , m ));
245+ String bmSig = "" ;
246+ if (!isConstructor (m )) {
247+ bmSig += ": " + getTypeScriptTypeFromJavaType (classInterface , m .getReturnType ());
248+ }
249+ sbContent .appendln (bmSig + ";" );
250+ }
251+
252+ sbContent .appendln (tabs + "});" );
253+ }
254+
255+ private void generateInterfaceConstructorCommentBlock (JavaClass classInterface , String tabs ) {
256+ sbContent .appendln (tabs + "/**" );
257+ sbContent .appendln (tabs + " * Constructs a new instance of the " + classInterface .getClassName () + " interface with the provided implementation." );
258+ sbContent .appendln (tabs + " * @param implementation - allows implementor to define their own logic for all public methods." );
259+ sbContent .appendln (tabs + " */" );
260+ }
261+
262+ private List <JavaClass > getAllInterfaces (JavaClass classInterface ) {
263+ ArrayList <JavaClass > interfaces = new ArrayList <>();
264+
265+ Queue <JavaClass > classQueue = new LinkedList <>();
266+ classQueue .add (classInterface );
267+
268+ while (!classQueue .isEmpty ()) {
269+ JavaClass clazz = classQueue .poll ();
270+
271+ interfaces .add (clazz );
272+
273+ String [] interfaceNames = clazz .getInterfaceNames ();
274+
275+ for (String intface : interfaceNames ) {
276+ JavaClass clazz1 = ClassRepo .findClass (intface );
277+
278+ classQueue .add (clazz1 );
279+ }
280+ }
281+
282+ return interfaces ;
283+ }
284+
285+ private List <Method > getAllInterfacesMethods (List <JavaClass > interfaces ) {
286+ ArrayList <Method > allInterfacesMethods = new ArrayList <>();
287+
288+ for (JavaClass clazz : interfaces ) {
289+ Method [] intfaceMethods = clazz .getMethods ();
290+ allInterfacesMethods .addAll (Arrays .asList (intfaceMethods ));
291+ }
292+
293+ return allInterfacesMethods ;
294+ }
295+
296+ private Set <Field > getAllInterfacesFields (List <JavaClass > interfaces ) {
297+ HashSet <Field > allInterfacesFields = new HashSet <>();
298+
299+ for (JavaClass clazz : interfaces ) {
300+ allInterfacesFields .addAll (Arrays .asList (clazz .getFields ()));
301+ }
302+
303+ return allInterfacesFields ;
304+ }
210305 //method related
211306 private void processMethod (Method m , JavaClass clazz ) {
212307
@@ -490,4 +585,20 @@ private String getTabs(int count) {
490585 String tabs = new String (new char [count ]).replace ("\0 " , "\t " );
491586 return tabs ;
492587 }
588+
589+ private void overrideFieldComparator () {
590+ BCELComparator cmp = Field .getComparator ();
591+
592+ Field .setComparator (new BCELComparator () {
593+ @ Override
594+ public boolean equals (Object o , Object o1 ) {
595+ return ((Field )o ).getName ().equals (((Field ) o1 ).getName ());
596+ }
597+
598+ @ Override
599+ public int hashCode (Object o ) {
600+ return cmp .hashCode (o );
601+ }
602+ });
603+ }
493604}
0 commit comments