14
14
*/
15
15
package org .walkmod .javalang .compiler .types ;
16
16
17
+ import java .io .ByteArrayOutputStream ;
17
18
import java .io .File ;
18
19
import java .io .IOException ;
20
+ import java .io .InputStream ;
19
21
import java .lang .reflect .Modifier ;
20
22
import java .net .URLClassLoader ;
21
23
import java .util .*;
22
- import java .util .jar .JarEntry ;
23
- import java .util .jar .JarFile ;
24
24
25
+ import org .objectweb .asm .ClassReader ;
26
+ import org .objectweb .asm .Opcodes ;
27
+ import org .objectweb .asm .tree .InnerClassNode ;
25
28
import org .walkmod .javalang .ast .CompilationUnit ;
26
29
import org .walkmod .javalang .ast .ImportDeclaration ;
27
30
import org .walkmod .javalang .ast .Node ;
34
37
import org .walkmod .javalang .ast .body .TypeDeclaration ;
35
38
import org .walkmod .javalang .ast .expr .ObjectCreationExpr ;
36
39
import org .walkmod .javalang .ast .expr .QualifiedNameExpr ;
37
- import org .walkmod .javalang .ast .type .Type ;
38
40
import org .walkmod .javalang .compiler .actions .LoadStaticImportsAction ;
39
41
import org .walkmod .javalang .compiler .providers .SymbolActionProvider ;
40
- import org .walkmod .javalang .compiler .symbols .ASTSymbolTypeResolver ;
41
42
import org .walkmod .javalang .compiler .symbols .ReferenceType ;
42
43
import org .walkmod .javalang .compiler .symbols .Scope ;
43
44
import org .walkmod .javalang .compiler .symbols .Symbol ;
@@ -450,13 +451,15 @@ public void visit(ImportDeclaration id, T context) {
450
451
/**
451
452
* @param importedInner {@link @see #resolveSymbolName}
452
453
*/
453
- private void loadNestedClasses (Class <?> clazz , boolean imported , Node node , final boolean importedInner ) {
454
- Class <?>[] innerClasses = clazz .getDeclaredClasses ();
455
- if (innerClasses != null ) {
456
- for (int i = 0 ; i < innerClasses .length ; i ++) {
457
- if (!Modifier .isPrivate (innerClasses [i ].getModifiers ())) {
458
- String fullName = innerClasses [i ].getName ();
459
- SymbolType st = new SymbolType (innerClasses [i ]);
454
+ private void loadNestedClasses (ASMClass clazz , boolean imported , Node node , final boolean importedInner ) {
455
+
456
+ if (clazz .innerClasses != null ) {
457
+ Iterator <InnerClassNode > it = clazz .innerClasses .iterator ();
458
+ while (it .hasNext ()) {
459
+ InnerClassNode innerClass = it .next ();
460
+ if (innerClass .access != Opcodes .ACC_PRIVATE ) {
461
+ String fullName = innerClass .name ;
462
+ SymbolType st = new SymbolType (fullName );
460
463
symbolTable .pushSymbol (resolveSymbolName (fullName , imported , importedInner ), ReferenceType .TYPE , st ,
461
464
node , true );
462
465
}
@@ -465,43 +468,80 @@ private void loadNestedClasses(Class<?> clazz, boolean imported, Node node, fina
465
468
}
466
469
}
467
470
471
+ private static byte [] readStream (InputStream inputStream , boolean close ) throws IOException {
472
+ if (inputStream == null ) {
473
+ throw new IOException ("Class not found" );
474
+ } else {
475
+ try {
476
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream ();
477
+ byte [] data = new byte [4096 ];
478
+
479
+ int bytesRead ;
480
+ while ((bytesRead = inputStream .read (data , 0 , data .length )) != -1 ) {
481
+ outputStream .write (data , 0 , bytesRead );
482
+ }
483
+
484
+ outputStream .flush ();
485
+ byte [] var5 = outputStream .toByteArray ();
486
+ return var5 ;
487
+ } finally {
488
+ if (close ) {
489
+ inputStream .close ();
490
+ }
491
+
492
+ }
493
+ }
494
+ }
495
+
496
+ private ASMClass getASMClass (String name ) throws IOException {
497
+ ASMClass visitor = new ASMClass ();
498
+ ClassReader reader = new ClassReader (readStream (
499
+ classLoader .getResourceAsStream (name .replace ('.' , '/' ) + ".class" ),
500
+ true ));
501
+ reader .accept (visitor , 1 );
502
+ return visitor ;
503
+ }
504
+
468
505
private void addType (final String name , boolean imported , Node node , List <SymbolAction > actions ) {
469
506
if (classLoader != null && name != null ) {
507
+
508
+ //check if the file exists in the classpath
470
509
try {
471
- Class <?> clazz = Class .forName (name , false , classLoader );
472
- if (!Modifier .isPrivate (clazz .getModifiers ()) && !clazz .isAnonymousClass ()) {
510
+
511
+ ASMClass asmClass = getASMClass (name );
512
+
513
+ if (!asmClass .isPrivate () && !asmClass .isAnonymous ()){ //anonymous?
473
514
474
515
boolean overrideSimpleName = true ;
475
516
476
- SymbolType st = new SymbolType (clazz );
517
+ SymbolType st = new SymbolType (name );
477
518
478
519
if (node instanceof ImportDeclaration ) {
479
520
ImportDeclaration id = (ImportDeclaration ) node ;
480
521
if (id .isAsterisk ()) {
481
522
overrideSimpleName = false ;
482
523
}
483
524
}
484
- symbolTable .pushSymbol (resolveSymbolName (name , imported , false ), ReferenceType . TYPE , st , node ,
485
- actions , overrideSimpleName );
525
+ symbolTable .pushSymbol (resolveSymbolName (name , imported , false ),
526
+ ReferenceType . TYPE , st , node , actions , overrideSimpleName );
486
527
487
- if (clazz .isMemberClass ()) {
488
- String cname = clazz .getCanonicalName ();
489
- if (cname != null ) {
490
- symbolTable .pushSymbol (cname , ReferenceType .TYPE , st , node , actions , true );
528
+ if (asmClass .isMemberClass ()) {
491
529
492
- Package pkg = clazz .getPackage ();
493
- if (pkg != null ) {
494
- if (pkg .getName ().equals (packageName ) && node != null ) {
530
+ symbolTable .pushSymbol (asmClass .getCanonicalName (), ReferenceType .TYPE , st , node , actions , true );
495
531
496
- symbolTable .pushSymbol (clazz .getSimpleName (), ReferenceType .TYPE , st , node , actions ,
497
- true );
498
- }
532
+ String pkg = asmClass .getPackage ();
533
+ if (pkg != null ) {
534
+ if (pkg .equals (packageName ) && node != null ) {
535
+
536
+ symbolTable .pushSymbol (asmClass .getSimpleName (), ReferenceType .TYPE , st , node , actions ,
537
+ true );
499
538
}
500
539
}
540
+
501
541
}
502
- loadNestedClasses (clazz , imported , node , true );
542
+ loadNestedClasses (asmClass , imported , node , true );
503
543
}
504
- } catch (ClassNotFoundException e ) {
544
+ } catch (IOException e ) {
505
545
loadInnerClass (name , imported , node , actions );
506
546
} catch (IncompatibleClassChangeError e2 ) {
507
547
int index = name .lastIndexOf ("$" );
@@ -525,19 +565,19 @@ private void loadInnerClass(String name, boolean imported, Node node, List<Symbo
525
565
String internalName = preffix + "$" + suffix ;
526
566
527
567
try {
528
- Class <?> clazz = Class . forName (internalName , false , classLoader );
568
+ ASMClass asmClass = getASMClass (internalName );
529
569
530
- if (!Modifier .isPrivate (clazz . getModifiers () )) {
570
+ if (!asmClass .isPrivate ()) {
531
571
String keyName = resolveSymbolName (internalName , imported , false );
532
- SymbolType st = new SymbolType (clazz );
572
+ SymbolType st = new SymbolType (internalName );
533
573
Symbol <?> pushedSymbol =
534
574
symbolTable .pushSymbol (keyName , ReferenceType .TYPE , st , node , actions , true );
535
575
if (pushedSymbol != null ) {
536
- loadNestedClasses (clazz , imported , node , false );
576
+ loadNestedClasses (asmClass , imported , node , false );
537
577
}
538
578
539
579
}
540
- } catch (ClassNotFoundException e1 ) {
580
+ } catch (IOException e1 ) {
541
581
int indexDot = internalName .indexOf ("." );
542
582
if (indexDot == -1 ) {
543
583
throw new RuntimeException ("The referenced class " + internalName + " does not exists" );
0 commit comments