@@ -431,124 +431,130 @@ static Collection<TypeAbstraction> getPossibleTypes(int valueNumber, TypeInferen
431
431
return ret ;
432
432
}
433
433
434
- public static Collection <TypeAbstraction > getPossibleTypesInterprocedurally (CGNode node , int valueNumber ,
435
- EclipseProjectAnalysisEngine <InstanceKey > engine , OrderingInference orderingInference )
434
+ public static Collection <TypeAbstraction > getPossibleTypesInterprocedurally (Collection < CGNode > nodeCollection ,
435
+ int valueNumber , EclipseProjectAnalysisEngine <InstanceKey > engine , OrderingInference orderingInference )
436
436
throws NoniterableException , NoninstantiableException , CannotExtractSpliteratorException ,
437
437
UTFDataFormatException , JavaModelException {
438
438
Collection <TypeAbstraction > ret = new HashSet <>();
439
439
440
- PointerKey valueKey = engine .getHeapGraph ().getHeapModel ().getPointerKeyForLocal (node , valueNumber );
441
- LOGGER .fine (() -> "Value pointer key is: " + valueKey );
442
-
443
- OrdinalSet <InstanceKey > pointsToSet = engine .getPointerAnalysis ().getPointsToSet (valueKey );
444
- assert pointsToSet != null ;
445
- LOGGER .fine (() -> "PointsTo set is: " + pointsToSet );
446
-
447
- for (InstanceKey instanceKey : pointsToSet ) {
448
- IClass concreteClass = instanceKey .getConcreteType ();
449
-
450
- if (!(concreteClass instanceof SyntheticClass )) {
451
- LOGGER .fine (() -> "Found non-synthetic concrete type: " + concreteClass );
452
-
453
- // Workaround #38, problem seemingly with generics.
454
- // Due to type erasure, we may have the problem if the return
455
- // type is java.lang.Object.
456
- // Find the return type of the instruction.
457
- TypeInference inference = TypeInference .make (node .getIR (), false );
458
- Collection <TypeAbstraction > returnTypes = Util .getPossibleTypes (valueNumber , inference );
459
-
460
- // for each return type.
461
- for (TypeAbstraction rType : returnTypes ) {
462
- PointType concreteType = new PointType (concreteClass );
463
-
464
- if (rType .getType ().getReference ().equals (TypeReference .JavaLangObject )) {
465
- IR ir = node .getIR ();
466
- IMethod method = ir .getMethod ();
467
- IBytecodeMethod bytecodeMethod = (IBytecodeMethod ) method ;
468
-
469
- // get the definition instruction.
470
- SSAInvokeInstruction def = (SSAInvokeInstruction ) node .getDU ().getDef (valueNumber );
471
-
472
- // which index is it into the instruction array?
473
- int instructionIndex = Util .indexOf (ir .getInstructions (), def );
474
-
475
- // get the bytecode index.
476
- int bytecodeIndex ;
477
- try {
478
- bytecodeIndex = bytecodeMethod .getBytecodeIndex (instructionIndex );
479
- } catch (InvalidClassFileException e ) {
480
- throw new IllegalArgumentException (
481
- "Value number: " + valueNumber + " does not have a definition (" + instructionIndex
482
- + ") corresponding to a bytecode index." ,
483
- e );
484
- }
440
+ // for each call graph node.
441
+ for (CGNode node : nodeCollection ) {
442
+ // get the pointer key.
443
+ PointerKey valueKey = engine .getHeapGraph ().getHeapModel ().getPointerKeyForLocal (node , valueNumber );
444
+ LOGGER .fine (() -> "Value pointer key is: " + valueKey );
445
+
446
+ OrdinalSet <InstanceKey > pointsToSet = engine .getPointerAnalysis ().getPointsToSet (valueKey );
447
+ assert pointsToSet != null ;
448
+ LOGGER .fine (() -> "PointsTo set is: " + pointsToSet );
449
+
450
+ for (InstanceKey instanceKey : pointsToSet ) {
451
+ IClass concreteClass = instanceKey .getConcreteType ();
452
+
453
+ if (!(concreteClass instanceof SyntheticClass )) {
454
+ LOGGER .fine (() -> "Found non-synthetic concrete type: " + concreteClass );
455
+
456
+ // Workaround #38, problem seemingly with generics.
457
+ // Due to type erasure, we may have the problem if the return
458
+ // type is java.lang.Object.
459
+ // Find the return type of the instruction.
460
+ TypeInference inference = TypeInference .make (node .getIR (), false );
461
+ Collection <TypeAbstraction > returnTypes = Util .getPossibleTypes (valueNumber , inference );
462
+
463
+ // for each return type.
464
+ for (TypeAbstraction rType : returnTypes ) {
465
+ PointType concreteType = new PointType (concreteClass );
466
+
467
+ if (rType .getType ().getReference ().equals (TypeReference .JavaLangObject )) {
468
+ IR ir = node .getIR ();
469
+ IMethod method = ir .getMethod ();
470
+ IBytecodeMethod bytecodeMethod = (IBytecodeMethod ) method ;
471
+
472
+ // get the definition instruction.
473
+ SSAInvokeInstruction def = (SSAInvokeInstruction ) node .getDU ().getDef (valueNumber );
474
+
475
+ // which index is it into the instruction array?
476
+ int instructionIndex = Util .indexOf (ir .getInstructions (), def );
477
+
478
+ // get the bytecode index.
479
+ int bytecodeIndex ;
480
+ try {
481
+ bytecodeIndex = bytecodeMethod .getBytecodeIndex (instructionIndex );
482
+ } catch (InvalidClassFileException e ) {
483
+ throw new IllegalArgumentException (
484
+ "Value number: " + valueNumber + " does not have a definition ("
485
+ + instructionIndex + ") corresponding to a bytecode index." ,
486
+ e );
487
+ }
485
488
486
- // get the source information
487
- SourcePosition sourcePosition ;
488
- try {
489
- sourcePosition = method .getSourcePosition (bytecodeIndex );
490
- } catch (InvalidClassFileException e ) {
491
- throw new IllegalArgumentException (
492
- "Value number: " + valueNumber + " does not have bytecode index (" + bytecodeIndex
493
- + ") corresponding to a bytecode index." ,
494
- e );
495
- }
489
+ // get the source information
490
+ SourcePosition sourcePosition ;
491
+ try {
492
+ sourcePosition = method .getSourcePosition (bytecodeIndex );
493
+ } catch (InvalidClassFileException e ) {
494
+ throw new IllegalArgumentException (
495
+ "Value number: " + valueNumber + " does not have bytecode index ("
496
+ + bytecodeIndex + ") corresponding to a bytecode index." ,
497
+ e );
498
+ }
496
499
497
- // let's assume that the source file is in the same project.
498
- IJavaProject enclosingProject = engine .getProject ();
499
-
500
- String fqn = method .getDeclaringClass ().getName ().getPackage ().toUnicodeString () + "."
501
- + method .getDeclaringClass ().getName ().getClassName ().toUnicodeString ();
502
- IType type = enclosingProject .findType (fqn .replace ('/' , '.' ));
503
- // FIXME: Need to (i) exclude from result timer and (ii) use the cache in
504
- // ConvertToParallelStreamRefactoringProcessor #141.
505
- CompilationUnit unit = RefactoringASTParser .parseWithASTProvider (type .getTypeRoot (), true ,
506
- null );
507
-
508
- // We have the CompilationUnit corresponding to the instruction's file. Can we
509
- // correlate the instruction to the method invocation in the AST?
510
- MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation (unit ,
511
- sourcePosition , def .getCallSite ().getDeclaredTarget ());
512
-
513
- // what does the method return?
514
- ITypeBinding genericReturnType = correspondingInvocation .resolveMethodBinding ().getReturnType ();
515
-
516
- // Is it compatible with the concrete type we got from WALA? But first, we'll
517
- // need to translate the Eclipse JDT type over to a IClass.
518
- TypeReference genericTypeRef = getJDTIdentifyMapper (correspondingInvocation )
519
- .getTypeRef (genericReturnType );
520
- IClass genericClass = node .getClassHierarchy ().lookupClass (genericTypeRef );
521
-
522
- boolean assignableFrom = node .getClassHierarchy ().isAssignableFrom (genericClass , concreteClass );
523
-
524
- // if it's assignable.
525
- if (assignableFrom )
526
- // would the ordering be consistent?
527
- if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), concreteType ,
528
- orderingInference )) {
529
- // if so, add it.
530
- LOGGER .fine ("Add type straight up: " + concreteType );
531
- ret .add (concreteType );
532
- } else {
533
- // otherwise, would the generic type cause the
534
- // ordering to be inconsistent?
535
- PointType genericType = new PointType (genericClass );
536
-
537
- if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), genericType ,
500
+ // let's assume that the source file is in the same project.
501
+ IJavaProject enclosingProject = engine .getProject ();
502
+
503
+ String fqn = method .getDeclaringClass ().getName ().getPackage ().toUnicodeString () + "."
504
+ + method .getDeclaringClass ().getName ().getClassName ().toUnicodeString ();
505
+ IType type = enclosingProject .findType (fqn .replace ('/' , '.' ));
506
+ // FIXME: Need to (i) exclude from result timer and (ii) use the cache in
507
+ // ConvertToParallelStreamRefactoringProcessor #141.
508
+ CompilationUnit unit = RefactoringASTParser .parseWithASTProvider (type .getTypeRoot (), true ,
509
+ null );
510
+
511
+ // We have the CompilationUnit corresponding to the instruction's file. Can we
512
+ // correlate the instruction to the method invocation in the AST?
513
+ MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation (unit ,
514
+ sourcePosition , def .getCallSite ().getDeclaredTarget ());
515
+
516
+ // what does the method return?
517
+ ITypeBinding genericReturnType = correspondingInvocation .resolveMethodBinding ()
518
+ .getReturnType ();
519
+
520
+ // Is it compatible with the concrete type we got from WALA? But first, we'll
521
+ // need to translate the Eclipse JDT type over to a IClass.
522
+ TypeReference genericTypeRef = getJDTIdentifyMapper (correspondingInvocation )
523
+ .getTypeRef (genericReturnType );
524
+ IClass genericClass = node .getClassHierarchy ().lookupClass (genericTypeRef );
525
+
526
+ boolean assignableFrom = node .getClassHierarchy ().isAssignableFrom (genericClass ,
527
+ concreteClass );
528
+
529
+ // if it's assignable.
530
+ if (assignableFrom )
531
+ // would the ordering be consistent?
532
+ if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), concreteType ,
538
533
orderingInference )) {
539
- LOGGER .fine ("Defaulting to generic type: " + genericType );
540
- ret .add (genericType );
541
- } else {
542
- // fall back to the concrete type.
543
- LOGGER .fine ("Defaulting to concrete type eventhough it isn't consistent: "
544
- + concreteType );
534
+ // if so, add it.
535
+ LOGGER .fine ("Add type straight up: " + concreteType );
545
536
ret .add (concreteType );
537
+ } else {
538
+ // otherwise, would the generic type cause the
539
+ // ordering to be inconsistent?
540
+ PointType genericType = new PointType (genericClass );
541
+
542
+ if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), genericType ,
543
+ orderingInference )) {
544
+ LOGGER .fine ("Defaulting to generic type: " + genericType );
545
+ ret .add (genericType );
546
+ } else {
547
+ // fall back to the concrete type.
548
+ LOGGER .fine ("Defaulting to concrete type eventhough it isn't consistent: "
549
+ + concreteType );
550
+ ret .add (concreteType );
551
+ }
546
552
}
547
- }
548
- } else {
549
- // just add it.
550
- LOGGER . fine ( "Add type straight up: " + concreteType );
551
- ret . add ( concreteType );
553
+ } else {
554
+ // just add it.
555
+ LOGGER . fine ( "Add type straight up: " + concreteType );
556
+ ret . add ( concreteType );
557
+ }
552
558
}
553
559
}
554
560
}
0 commit comments