@@ -431,124 +431,130 @@ static Collection<TypeAbstraction> getPossibleTypes(int valueNumber, TypeInferen
431431 return ret ;
432432 }
433433
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 )
436436 throws NoniterableException , NoninstantiableException , CannotExtractSpliteratorException ,
437437 UTFDataFormatException , JavaModelException {
438438 Collection <TypeAbstraction > ret = new HashSet <>();
439439
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+ }
485488
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+ }
496499
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 ,
538533 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 );
545536 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+ }
546552 }
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+ }
552558 }
553559 }
554560 }
0 commit comments