55
66import org .apache .bcel .classfile .JavaClass ;
77import org .apache .bcel .classfile .Method ;
8- import org .apache .commons .io .FileUtils ;
98import org .nativescript .staticbindinggenerator .files .FileSystemHelper ;
109import org .nativescript .staticbindinggenerator .files .impl .ClassesCollection ;
1110import org .nativescript .staticbindinggenerator .files .impl .FileSystemHelperImpl ;
1514import org .nativescript .staticbindinggenerator .generating .parsing .checkers .impl .ImplementationObjectCheckerImpl ;
1615import org .nativescript .staticbindinggenerator .generating .parsing .classes .hierarchy .generics .GenericHierarchyView ;
1716import org .nativescript .staticbindinggenerator .generating .parsing .classes .hierarchy .generics .GenericParameters ;
17+ import org .nativescript .staticbindinggenerator .generating .parsing .classes .hierarchy .generics .GenericsAwareClassHierarchyParser ;
1818import org .nativescript .staticbindinggenerator .generating .parsing .classes .hierarchy .generics .impl .GenericSignatureReader ;
1919import org .nativescript .staticbindinggenerator .generating .parsing .classes .hierarchy .generics .impl .GenericsAwareClassHierarchyParserImpl ;
2020import org .nativescript .staticbindinggenerator .generating .parsing .methods .InheritedMethodsCollector ;
3535import org .nativescript .staticbindinggenerator .generating .writing .impl .MethodsWriterImpl ;
3636import org .nativescript .staticbindinggenerator .generating .writing .impl .PackageNameWriterImpl ;
3737import org .nativescript .staticbindinggenerator .naming .BcelNamingUtil ;
38+ import org .nativescript .staticbindinggenerator .naming .JavaClassNames ;
3839
3940import java .io .BufferedReader ;
4041import java .io .File ;
4344import java .io .IOException ;
4445import java .io .InputStreamReader ;
4546import java .io .PrintStream ;
46- import java .nio .charset .Charset ;
4747import java .nio .file .Files ;
4848import java .nio .file .Paths ;
4949import java .util .ArrayList ;
@@ -279,61 +279,99 @@ private String getSimpleClassname(String classname) {
279279 }
280280
281281 private void writeBinding (Writer w , DataRow dataRow , JavaClass clazz , String packageName , String name ) {
282- GenericHierarchyView genView = new GenericsAwareClassHierarchyParserImpl (new GenericSignatureReader (), classes ).getClassHierarchy (clazz );
282+ GenericsAwareClassHierarchyParser genericsAwareClassHierarchyParser = new GenericsAwareClassHierarchyParserImpl (new GenericSignatureReader (), classes );
283+ List <JavaClass > userImplementedInterfaces = getInterfacesFromCache (Arrays .asList (dataRow .getInterfaces ()));
284+
285+ if (clazz .isInterface ()) {
286+ userImplementedInterfaces .add (clazz );
287+ clazz = getClass (JavaClassNames .BASE_JAVA_CLASS_NAME );
288+ }
289+
290+ GenericHierarchyView genView = createExtendedClassGenericHierarchyView (genericsAwareClassHierarchyParser , clazz );
291+ Map <JavaClass , GenericHierarchyView > interfaceGenericHierarchyViews = createInterfaceGenericHierarchyViews (genericsAwareClassHierarchyParser , userImplementedInterfaces );
283292
284293 writePackageNameToWriter (w , packageName );
285294 writeImportsToWriter (w , clazz , packageName );
286- writeClassBeginningToWriter (w , clazz , dataRow . getInterfaces () , name , dataRow , genView );
295+ writeClassBeginningToWriter (w , clazz , userImplementedInterfaces , name , dataRow , genView , interfaceGenericHierarchyViews );
287296 writeFieldsToWriter (w , clazz );
288297 writeConstructorsToWriter (w , clazz , dataRow , name , genView );
289- writeMethodsToWriter (w , genView , clazz , Arrays .asList (dataRow .getMethods ()), Arrays . asList ( dataRow . getInterfaces ()) , packageName );
298+ writeMethodsToWriter (w , genView , interfaceGenericHierarchyViews , clazz , Arrays .asList (dataRow .getMethods ()), userImplementedInterfaces , packageName );
290299 writeClassEndToWriter (w );
291300 }
292301
293- private void writeClassBeginningToWriter (Writer writer , JavaClass clazz , String [] implementedInterfacesNames , String generatedClassName , DataRow dataRow , GenericHierarchyView genericHierarchyView ) {
302+ private Map <JavaClass , GenericHierarchyView > createInterfaceGenericHierarchyViews (GenericsAwareClassHierarchyParser genericsAwareClassHierarchyParser , List <JavaClass > implementedInterfaces ) {
303+ Map <JavaClass , GenericHierarchyView > interfaceGenericHierarchyViews = new HashMap <>(implementedInterfaces .size ());
304+
305+ for (JavaClass implementedInterface : implementedInterfaces ) {
306+ GenericHierarchyView genericHierarchyView = genericsAwareClassHierarchyParser .getClassHierarchy (implementedInterface );
307+ interfaceGenericHierarchyViews .put (implementedInterface , genericHierarchyView );
308+ }
309+
310+ return interfaceGenericHierarchyViews ;
311+ }
312+
313+ private GenericHierarchyView createExtendedClassGenericHierarchyView (GenericsAwareClassHierarchyParser genericsAwareClassHierarchyParser , JavaClass extendedClass ) {
314+ return genericsAwareClassHierarchyParser .getClassHierarchy (extendedClass );
315+ }
316+
317+ private void writeClassBeginningToWriter (Writer writer , JavaClass clazz , List <JavaClass > implementedInterfaces , String generatedClassName , DataRow dataRow , GenericHierarchyView genericHierarchyView , Map <JavaClass , GenericHierarchyView > interfaceGenericHierarchyViews ) {
294318 ClassWriter classWriter = new ClassWriterImpl (writer );
295- StringBuilder extendedClassNameBuilder = new StringBuilder ();
296- extendedClassNameBuilder .append (BcelNamingUtil .resolveClassName (clazz .getClassName ()));
297319
298- GenericParameters initialClassGenericParameters = genericHierarchyView .getInitialClassGenericParameters ();
320+ boolean hasCustomJsName = !dataRow .getFilename ().isEmpty ();
321+
322+ List <String > implementedInterfacesNames = mapNamesWithGenericArgumentsIfNecessary (implementedInterfaces , interfaceGenericHierarchyViews );
323+ String extendedClassName = mapNameWithGenericArgumentsIfNecessary (clazz , genericHierarchyView );
324+
325+ if (hasCustomJsName ) {
326+ classWriter .writeBeginningOfNamedChildClass (generatedClassName , dataRow .getJsFilename (), extendedClassName , implementedInterfacesNames );
327+ } else {
328+ classWriter .writeBeginningOfChildClass (generatedClassName , extendedClassName , implementedInterfacesNames );
329+ }
330+ }
331+
332+ private String mapNameWithGenericArgumentsIfNecessary (JavaClass extendedClass , GenericHierarchyView extendedClassGenericHierarchyView ) {
333+ return getClassNameWithPossibleGenericArguments (extendedClass , extendedClassGenericHierarchyView );
334+ }
335+
336+ private List <String > mapNamesWithGenericArgumentsIfNecessary (List <JavaClass > implementedInterfaces , Map <JavaClass , GenericHierarchyView > interfaceGenericHierarchyViews ) {
337+ List <String > res = new ArrayList <>();
338+
339+ for (JavaClass implementedInterface : implementedInterfaces ) {
340+ GenericHierarchyView genericHierarchyView = interfaceGenericHierarchyViews .get (implementedInterface );
341+ String className = getClassNameWithPossibleGenericArguments (implementedInterface , genericHierarchyView );
342+ res .add (className );
343+ }
344+
345+ return res ;
346+ }
347+
348+ private String getClassNameWithPossibleGenericArguments (JavaClass classToCheck , GenericHierarchyView classToCheckGenericHierarchyView ) {
349+ GenericParameters initialClassGenericParameters = classToCheckGenericHierarchyView .getInitialClassGenericParameters ();
350+ StringBuilder classNameBuilder = new StringBuilder ();
351+ classNameBuilder .append (BcelNamingUtil .resolveClassName (classToCheck .getClassName ()));
299352
300353 if (initialClassGenericParameters != null ) {
301354 Map <String , String > initialClassGenericParametersMap = initialClassGenericParameters .getGenericParameters ();
302355 int initialClassGenericParametersMapCount = initialClassGenericParametersMap .size ();
303356
304357 if (initialClassGenericParametersMapCount > 0 ) {
305- extendedClassNameBuilder .append ('<' );
358+ classNameBuilder .append ('<' );
306359 int parameterCounter = 0 ;
307360 for (Map .Entry <String , String > genericParameter : initialClassGenericParametersMap .entrySet ()) {
308361 String resolvedGeneriParameterValue = BcelNamingUtil .resolveClassName (genericParameter .getValue ());
309- extendedClassNameBuilder .append (resolvedGeneriParameterValue );
362+ classNameBuilder .append (resolvedGeneriParameterValue );
310363
311364 if (parameterCounter != initialClassGenericParametersMapCount - 1 ) {
312- extendedClassNameBuilder .append (", " );
365+ classNameBuilder .append (", " );
313366 parameterCounter += 1 ;
314367 }
315368 }
316- extendedClassNameBuilder .append ('>' );
369+ classNameBuilder .append ('>' );
317370 }
318371
319372 }
320373
321- boolean hasCustomJsName = !dataRow .getFilename ().isEmpty ();
322-
323- String extendedClassName = extendedClassNameBuilder .toString ();
324- if (hasCustomJsName ) {
325- if (clazz .isInterface ()) { // extending an interface
326- classWriter .writeBeginningOfNamedClassImplementingSingleInterface (generatedClassName , dataRow .getJsFilename (), extendedClassName );
327- } else {
328- classWriter .writeBeginningOfNamedChildClass (generatedClassName , dataRow .getJsFilename (), extendedClassName , Arrays .asList (implementedInterfacesNames ));
329- }
330- } else {
331- if (clazz .isInterface ()) { // extending an interface
332- classWriter .writeBeginningOfClassImplementingSingleInterface (generatedClassName , extendedClassName );
333- } else {
334- classWriter .writeBeginningOfChildClass (generatedClassName , extendedClassName , Arrays .asList (implementedInterfacesNames ));
335- }
336- }
374+ return classNameBuilder .toString ();
337375 }
338376
339377 private void writeImportsToWriter (Writer writer , JavaClass clazz , String packageName ) {
@@ -372,32 +410,26 @@ private void writeConstructorsToWriter(Writer writer, JavaClass clazz, DataRow d
372410 boolean hasInitMethod = implementationObjectChecker .hasInitMethod (implObjectMethods );
373411 boolean hasInitMethod2 = !isApplicationClass && hasInitMethod ;
374412
375- boolean isInterface = clazz .isInterface ();
376- if (isInterface ) {
377- methodsWriter .writeDefaultConstructor (generatedClassName );
378- } else {
379- for (Method method : clazz .getMethods ()) {
380- if (method .getName ().equals ("<init>" ) && (method .isPublic () || method .isProtected ())) {
381- JavaMethod javaMethod = new JavaMethodImpl (method , clazz );
382- ReifiedJavaMethod reifiedJavaMethod = methodSignatureReifier .transformJavaMethod (javaMethod );
383- methodsWriter .writeConstructor (generatedClassName , reifiedJavaMethod , hasInitMethod2 );
384- }
413+ for (Method method : clazz .getMethods ()) {
414+ if (method .getName ().equals ("<init>" ) && (method .isPublic () || method .isProtected ())) {
415+ JavaMethod javaMethod = new JavaMethodImpl (method , clazz );
416+ ReifiedJavaMethod reifiedJavaMethod = methodSignatureReifier .transformJavaMethod (javaMethod );
417+ methodsWriter .writeConstructor (generatedClassName , reifiedJavaMethod , hasInitMethod2 );
385418 }
386419 }
387420 }
388421
389- private void writeMethodsToWriter (Writer writer , GenericHierarchyView genericHierarchyView , JavaClass clazz , List <String > userImplementedMethods , List <String > userImplementedInterfacesNames , String packageName ) {
390- boolean isInterface = clazz .isInterface ();
422+ private void writeMethodsToWriter (Writer writer , GenericHierarchyView genericHierarchyView , Map <JavaClass , GenericHierarchyView > interfaceGenericHierarchyViews , JavaClass clazz , List <String > userImplementedMethods , List <JavaClass > userImplementedInterfaces , String packageName ) {
391423 boolean isApplicationClass = androidClassChecker .isApplicationClass (clazz );
392424
393425 MethodsWriter methodsWriter = new MethodsWriterImpl (writer , suppressCallJSMethodExceptions , isApplicationClass );
394426
395- List <JavaClass > userImplementedInterfaces = getInterfacesFromCache (userImplementedInterfacesNames );
396427 InheritedMethodsCollector inheritedMethodsCollector = new InheritedMethodsCollectorImpl .Builder ()
397428 .forJavaClass (clazz )
398429 .withClassesCache (classes )
399430 .withAdditionalImplementedInterfaces (userImplementedInterfaces )
400431 .withGenericHierarchyView (genericHierarchyView )
432+ .withInterfacesGenericHierarchyViews (interfaceGenericHierarchyViews )
401433 .withPackageName (packageName )
402434 .build ();
403435
@@ -427,10 +459,8 @@ private void writeMethodsToWriter(Writer writer, GenericHierarchyView genericHie
427459 methodsWriter .writeGetInstanceMethod (normalizedClassName );
428460 }
429461
430- if (!isInterface ) {
431- methodsWriter .writeInternalRuntimeHashCodeMethod ();
432- methodsWriter .writeInternalRuntimeEqualsMethod ();
433- }
462+ methodsWriter .writeInternalRuntimeHashCodeMethod ();
463+ methodsWriter .writeInternalRuntimeEqualsMethod ();
434464 }
435465
436466 private boolean areAllArgumentsAndReturnTypePublic (ReifiedJavaMethod method ) {
@@ -490,4 +520,4 @@ private JavaClass getClass(String className) {
490520
491521 return clazz ;
492522 }
493- }
523+ }
0 commit comments