Community
Participate
Working Groups
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.
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) { } }
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)
(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; } }
(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?
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().
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.
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()
Update title according to comment 2.
+1
Released for 3.3M6. Added regression tests org.eclipse.jdt.core.tests.dom.ASTConverter15Test#test0249/0252
Verified for 3.3 M6 using build I20070320-0010.