@@ -374,98 +374,100 @@ public static Collection<TypeAbstraction> getPossibleTypesInterprocedurally(CGNo
374
374
// Find the return type of the instruction.
375
375
TypeInference inference = TypeInference .make (node .getIR (), false );
376
376
Collection <TypeAbstraction > returnTypes = Util .getPossibleTypes (valueNumber , inference );
377
- assert returnTypes .size () == 1 : "Not expecting more than one return type." ;
378
- TypeAbstraction rType = returnTypes .iterator ().next ();
379
377
380
- PointType concreteType = new PointType (concreteClass );
381
-
382
- if (rType .getType ().getReference ().equals (TypeReference .JavaLangObject )) {
383
- IR ir = node .getIR ();
384
- IMethod method = ir .getMethod ();
385
- IBytecodeMethod bytecodeMethod = (IBytecodeMethod ) method ;
386
-
387
- // get the definition instruction.
388
- SSAInvokeInstruction def = (SSAInvokeInstruction ) node .getDU ().getDef (valueNumber );
389
-
390
- // which index is it into the instruction array?
391
- int instructionIndex = Util .indexOf (ir .getInstructions (), def );
392
-
393
- // get the bytecode index.
394
- int bytecodeIndex ;
395
- try {
396
- bytecodeIndex = bytecodeMethod .getBytecodeIndex (instructionIndex );
397
- } catch (InvalidClassFileException e ) {
398
- throw new IllegalArgumentException (
399
- "Value number: " + valueNumber + " does not have a definition (" + instructionIndex
400
- + ") corresponding to a bytecode index." ,
401
- e );
402
- }
378
+ // for each return type.
379
+ for (TypeAbstraction rType : returnTypes ) {
380
+ PointType concreteType = new PointType (concreteClass );
381
+
382
+ if (rType .getType ().getReference ().equals (TypeReference .JavaLangObject )) {
383
+ IR ir = node .getIR ();
384
+ IMethod method = ir .getMethod ();
385
+ IBytecodeMethod bytecodeMethod = (IBytecodeMethod ) method ;
386
+
387
+ // get the definition instruction.
388
+ SSAInvokeInstruction def = (SSAInvokeInstruction ) node .getDU ().getDef (valueNumber );
389
+
390
+ // which index is it into the instruction array?
391
+ int instructionIndex = Util .indexOf (ir .getInstructions (), def );
392
+
393
+ // get the bytecode index.
394
+ int bytecodeIndex ;
395
+ try {
396
+ bytecodeIndex = bytecodeMethod .getBytecodeIndex (instructionIndex );
397
+ } catch (InvalidClassFileException e ) {
398
+ throw new IllegalArgumentException (
399
+ "Value number: " + valueNumber + " does not have a definition (" + instructionIndex
400
+ + ") corresponding to a bytecode index." ,
401
+ e );
402
+ }
403
403
404
- // get the source information
405
- SourcePosition sourcePosition ;
406
- try {
407
- sourcePosition = method .getSourcePosition (bytecodeIndex );
408
- } catch (InvalidClassFileException e ) {
409
- throw new IllegalArgumentException (
410
- "Value number: " + valueNumber + " does not have bytecode index (" + bytecodeIndex
411
- + ") corresponding to a bytecode index." ,
412
- e );
413
- }
404
+ // get the source information
405
+ SourcePosition sourcePosition ;
406
+ try {
407
+ sourcePosition = method .getSourcePosition (bytecodeIndex );
408
+ } catch (InvalidClassFileException e ) {
409
+ throw new IllegalArgumentException (
410
+ "Value number: " + valueNumber + " does not have bytecode index (" + bytecodeIndex
411
+ + ") corresponding to a bytecode index." ,
412
+ e );
413
+ }
414
414
415
- // let's assume that the source file is in the same project.
416
- IJavaProject enclosingProject = engine .getProject ();
417
-
418
- String fqn = method .getDeclaringClass ().getName ().getPackage ().toUnicodeString () + "."
419
- + method .getDeclaringClass ().getName ().getClassName ().toUnicodeString ();
420
- IType type = enclosingProject .findType (fqn .replace ('/' , '.' ));
421
- // FIXME: Need to (i) exclude from result timer and (ii) use the cache in
422
- // ConvertToParallelStreamRefactoringProcessor #141.
423
- CompilationUnit unit = RefactoringASTParser .parseWithASTProvider (type .getTypeRoot (), true , null );
424
-
425
- // We have the CompilationUnit corresponding to the instruction's file. Can we
426
- // correlate the instruction to the method invocation in the AST?
427
- MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation (unit , sourcePosition ,
428
- def .getCallSite ().getDeclaredTarget ());
429
-
430
- // what does the method return?
431
- ITypeBinding genericReturnType = correspondingInvocation .resolveMethodBinding ().getReturnType ();
432
-
433
- // Is it compatible with the concrete type we got from WALA? But first, we'll
434
- // need to translate the Eclipse JDT type over to a IClass.
435
- TypeReference genericTypeRef = getJDTIdentifyMapper (correspondingInvocation )
436
- .getTypeRef (genericReturnType );
437
- IClass genericClass = node .getClassHierarchy ().lookupClass (genericTypeRef );
438
-
439
- boolean assignableFrom = node .getClassHierarchy ().isAssignableFrom (genericClass , concreteClass );
440
-
441
- // if it's assignable.
442
- if (assignableFrom )
443
- // would the ordering be consistent?
444
- if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), concreteType ,
445
- orderingInference )) {
446
- // if so, add it.
447
- LOGGER .fine ("Add type straight up: " + concreteType );
448
- ret .add (concreteType );
449
- } else {
450
- // otherwise, would the generic type cause the
451
- // ordering to be inconsistent?
452
- PointType genericType = new PointType (genericClass );
453
-
454
- if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), genericType ,
415
+ // let's assume that the source file is in the same project.
416
+ IJavaProject enclosingProject = engine .getProject ();
417
+
418
+ String fqn = method .getDeclaringClass ().getName ().getPackage ().toUnicodeString () + "."
419
+ + method .getDeclaringClass ().getName ().getClassName ().toUnicodeString ();
420
+ IType type = enclosingProject .findType (fqn .replace ('/' , '.' ));
421
+ // FIXME: Need to (i) exclude from result timer and (ii) use the cache in
422
+ // ConvertToParallelStreamRefactoringProcessor #141.
423
+ CompilationUnit unit = RefactoringASTParser .parseWithASTProvider (type .getTypeRoot (), true ,
424
+ null );
425
+
426
+ // We have the CompilationUnit corresponding to the instruction's file. Can we
427
+ // correlate the instruction to the method invocation in the AST?
428
+ MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation (unit ,
429
+ sourcePosition , def .getCallSite ().getDeclaredTarget ());
430
+
431
+ // what does the method return?
432
+ ITypeBinding genericReturnType = correspondingInvocation .resolveMethodBinding ().getReturnType ();
433
+
434
+ // Is it compatible with the concrete type we got from WALA? But first, we'll
435
+ // need to translate the Eclipse JDT type over to a IClass.
436
+ TypeReference genericTypeRef = getJDTIdentifyMapper (correspondingInvocation )
437
+ .getTypeRef (genericReturnType );
438
+ IClass genericClass = node .getClassHierarchy ().lookupClass (genericTypeRef );
439
+
440
+ boolean assignableFrom = node .getClassHierarchy ().isAssignableFrom (genericClass , concreteClass );
441
+
442
+ // if it's assignable.
443
+ if (assignableFrom )
444
+ // would the ordering be consistent?
445
+ if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), concreteType ,
455
446
orderingInference )) {
456
- LOGGER .fine ("Defaulting to generic type: " + genericType );
457
- ret .add (genericType );
458
- } else {
459
- // fall back to the concrete type.
460
- LOGGER .fine (
461
- "Defaulting to concrete type eventhough it isn't consistent: " + concreteType );
447
+ // if so, add it.
448
+ LOGGER .fine ("Add type straight up: " + concreteType );
462
449
ret .add (concreteType );
450
+ } else {
451
+ // otherwise, would the generic type cause the
452
+ // ordering to be inconsistent?
453
+ PointType genericType = new PointType (genericClass );
454
+
455
+ if (wouldOrderingBeConsistent (Collections .unmodifiableCollection (ret ), genericType ,
456
+ orderingInference )) {
457
+ LOGGER .fine ("Defaulting to generic type: " + genericType );
458
+ ret .add (genericType );
459
+ } else {
460
+ // fall back to the concrete type.
461
+ LOGGER .fine ("Defaulting to concrete type eventhough it isn't consistent: "
462
+ + concreteType );
463
+ ret .add (concreteType );
464
+ }
463
465
}
464
- }
465
- } else {
466
- // just add it.
467
- LOGGER . fine ( "Add type straight up: " + concreteType );
468
- ret . add ( concreteType );
466
+ } else {
467
+ // just add it.
468
+ LOGGER . fine ( "Add type straight up: " + concreteType );
469
+ ret . add ( concreteType );
470
+ }
469
471
}
470
472
}
471
473
}
0 commit comments