Bug 174436 - API request: MethodInvocation/SuperMethodInvocation#isResolvedTypeInferredFromExpectedType()
Summary: API request: MethodInvocation/SuperMethodInvocation#isResolvedTypeInferredFro...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: 3.3 M6   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 174327
  Show dependency tree
 
Reported: 2007-02-16 08:54 EST by Markus Keller CLA
Modified: 2007-03-20 14:50 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2007-02-16 08:54:55 EST
I20070213-0907

To fix bug 174327, we need to find out whether an expression's resolved type was determined from the expression alone, or if the mechanism from JLS3 15.12.2.8 "Inferring Unresolved Type Arguments" was used.

To avoid reimplementing the complex inference in the refactoring, we need new API from the compiler.

I would propose boolean resolveAssignmentTypeInference() on org.eclipse.jdt.core.dom.Expression, but I'm open to other suggestions.
Comment 1 Markus Keller CLA 2007-02-23 13:59:44 EST
Actually, it should be sufficient if this is added to MethodInvocation and SuperMethodInvocation. E.g. in the example from bug 174327, it should return true for 'Collections.emptyMap()' but false if written as 'Collections.<String,String>emptyMap()':


import java.util.Collections;
import java.util.Map;

public class Try {
    void caller() {
        Map<String, String> emptyMap = Collections.emptyMap();
        method(emptyMap);
    }

    void method(Map<String, String> map) {
    }
}
Comment 2 Markus Keller CLA 2007-03-06 11:22:12 EST
From Philippe (disconnected at Boston airport):

I am wondering what exactly you need. Can you tell me which of the two
options matches precisely your request ?

1. did the second pass of inference (15.12.2.8) perform or not ?
2. did a better message send expression type (return type) got inferred
using 15.12.2.8 ?

The slight difference between (1) and (2) is that though 15.12.2.8 got
used, it may not have inferred anything different from before (i.e. when
the method return type doesn't refer to any type param for instance).

Assuming you want (2), then there is already some compiler support for
this.
Olivier - the boolean slot:
ParameterizedGenericMethodBinding#inferredReturnType is what you would need
to surface.

                  MethodBinding method = ((MessageSend)this.expression).
binding;
                  if (method instanceof ParameterizedGenericMethodBinding
                                    &&
((ParameterizedGenericMethodBinding)method).inferredReturnType) {

I believe this new API should live on MessageSend directly.
MethodInvocation#isResolvedTypeInferredFromExpectedType() (doc should point
at JLS 15.12.2.8)
Comment 3 Markus Keller CLA 2007-03-06 11:39:48 EST
(In reply to comment #2)
Yes, only (2) is interesting for us.

In this example, the predicate should return false for both invocations "inferred(1)":

public class Try2 {
    void caller() {
        Integer integer= inferred(1);
        method(integer);
        method(inferred(1));
    }

    void method(Integer arg) {
    }
    
    <Unused extends Number, B> B inferred(B b) {
    	return b;
    }
}
Comment 4 Olivier Thomann CLA 2007-03-06 22:24:26 EST
(In reply to comment #2)
> I believe this new API should live on MessageSend directly.
> MethodInvocation#isResolvedTypeInferredFromExpectedType() (doc should point
> at JLS 15.12.2.8)
If this is a flag on the ParameterizedGenericMethodBinding class, should the new API not be on IMethodBinding instead of the ASTNode itself?
Comment 5 Markus Keller CLA 2007-03-07 05:22:49 EST
The query cannot be on the method binding, since method bindings are unique, but the same parameterization can occur for [Super]MethodInvocations with different #isResolvedTypeInferredFromExpectedType().
This is similar to Expression#resolveBoxing().
Comment 6 Olivier Thomann CLA 2007-03-07 10:24:20 EST
Proposal could be:
/**
* Returns true if the resolved type has been inferred (JLS3 15.12.2.8), false otherwise.
* This information is available only when bindings are requested when the AST is being built.
*
* @return true if the resolved type has been inferred (JLS3 15.12.2.8), false otherwise
*/
public boolean isResolvedTypeInferredFromExpectedType()

defined on MethodInvocation and SuperMethodInvocation.
If ok, I'll request the API on the pmc list.
Comment 7 Olivier Thomann CLA 2007-03-07 10:28:40 EST
New proposal based on Markus comment:
/**
 * Returns true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise.
 * <p>
 * This information is available only when bindings are requested when the AST is being built
 * </p>.
 *
 * @return true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise
 * @since 3.3
 */
public boolean isResolvedTypeInferredFromExpectedType()
Comment 8 Olivier Thomann CLA 2007-03-07 11:25:12 EST
Update title according to comment 2.
Comment 9 Philipe Mulet CLA 2007-03-07 11:29:38 EST
+1
Comment 10 Olivier Thomann CLA 2007-03-07 11:56:57 EST
Released for 3.3M6.
Added regression tests org.eclipse.jdt.core.tests.dom.ASTConverter15Test#test0249/0252
Comment 11 Frederic Fusier CLA 2007-03-20 14:50:56 EDT
Verified for 3.3 M6 using build I20070320-0010.