Bug 84140 - The type binding of a vararg should be an array not a simple type
Summary: The type binding of a vararg should be an array not a simple type
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.0 M6   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-01 10:27 EST by Dirk Baeumer CLA
Modified: 2005-06-24 13:21 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Baeumer CLA 2005-02-01 10:27:16 EST
Example

public void bar(String... args){
}

The type returned form the SingleVariableDeclaration respresenting String...
args shouldn't be a simple type. It should either be a array type or a sepecial
vararg type. The problem is that is I ask the type for its binding I get a
binding representing String. But from a type system point of view this is String[].
Comment 1 Olivier Thomann CLA 2005-02-01 14:59:58 EST
If the ellipsis (...) is not part of the position of the type, then there is no
reason to get an array type.
The corresponding single variable declaration is set as var args. Then you know
this is a array type.
However I agree that the type binding corresponding to the type should be an
array binding.
Comment 2 Olivier Thomann CLA 2005-02-01 15:18:51 EST
In fact, it could be either way.
When you get a type binding that is not a array binding, it can match the
corresponding binding of the parameter in a method invocation. If you really
want the array type binding, then get the corresponding argument of the method
binding corresponding to the method declaration.

Jim, any comment? We might want to clarify the specs to know what type binding
is returned.
Comment 3 Dirk Baeumer CLA 2005-02-02 07:00:09 EST
After thinking about it again I am not sure anymore if the type should be an
array type. It should either be a special type (e.g. subclass of Type node) or a
simple type as it is right now. The special type could offer two resolve methods
to get both the binding for the simple and for the array type.

If you access the type via IVariableBinding return from the declaration you
already get an array type.
Comment 4 Jim des Rivieres CLA 2005-02-02 11:11:35 EST
I propose that we keep existing behavior and simply clarify the spec to say 
that the binding for the type Foo in void fun(Foo... args) will be the type as 
written (i.e. Foo), and that if you'd rather have the array type (Foo[]), ask 
the method binding for the type binding of the last parameter.
Comment 5 Dirk Baeumer CLA 2005-02-02 13:17:35 EST
Fine with me.
Comment 6 Jim des Rivieres CLA 2005-02-25 10:14:40 EST
Added the following clarifying notes. 

Olivier, please add a test to cover this case.

IMethodBinding.getParameterTypes()
 * Note that the binding for the last parameter type of a vararg method
 * declaration like <code>void fun(Foo... args)</code> is always for
 * an array type (i.e., <code>Foo[]</code>) reflecting the the way varargs
 * get compiled. However, the type binding obtained directly from
 * the <code>SingleVariableDeclaration</code> for the vararg parameter
 * is always for the type as written; i.e., the type binding for
 * <code>Foo</code>.

SingleVariableDeclaration.isVarargs
 * Note that the binding for the type <code>Foo</code>in the vararg method
 * declaration <code>void fun(Foo... args)</code> is always for the type as 
 * written; i.e., the type binding for <code>Foo</code>. However, if you
 * navigate from the method declaration to its method binding to the
 * type binding for its last parameter, the type binding for the vararg
 * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
 * the way vararg methods get compiled.
Comment 7 Olivier Thomann CLA 2005-02-25 13:34:21 EST
I will add test case to check we have the right behavior.
Comment 8 Olivier Thomann CLA 2005-02-25 13:55:59 EST
Regression tests added in ASTConverter15Test.test0131 and test0132.
Comment 9 Olivier Thomann CLA 2005-02-25 13:58:43 EST
Also test0143.
Comment 10 Dirk Baeumer CLA 2005-05-02 16:18:12 EDT
Reopening since these seems to have changed again:

I have the following test case:

public static final String format(String key,Object... args){
  return MessageFormat.format(key,args);
}

Asking the SingleVariableDeclaration representing Object... args in format if it
is a vararg I get true.  If I ask the declaration for its binding and than its
type I get an array type back.

fDeclaration.resolveBinding().getType().isArray()
	 (boolean) true

What are we going to do with this. We can't change this again since clients
might rely on the current behaviour.
Comment 11 Dirk Baeumer CLA 2005-05-02 16:18:38 EDT
Philippe, cc you since Olivier is on vacation.
Comment 12 Olivier Thomann CLA 2005-05-05 17:02:55 EDT
If you ask the declaration for its type and then its binding, you should get
Object and not Object[].
I cannot check myself, because Eclipse doesn't run on the machine I am using.
Comment 13 Dirk Baeumer CLA 2005-05-06 05:08:32 EDT
We should be REALLY REALLY careful changing this again. This might break
existing clients relying on the current implementation.
Comment 14 Olivier Thomann CLA 2005-05-07 17:20:40 EDT
If you do this:
fDeclaration.getType().resolveBinding().isArray()

do you get true?

I don't this so. I don't see what is wrong with your comment 10. It follows the
specifications. So I don't see what we could change. From my point of view,
there is absolutely nothing to change.
Comment 15 Dirk Baeumer CLA 2005-05-08 18:10:01 EDT
Yes,

in the given example

import java.text.MessageFormat;

public class Z {
	public static final String format(String key, Object... argssss){
		  return MessageFormat.format(key,argssss);
	}
	
	void use() {
		format("key", "value");
	}

}

when I ask the following question to fDeclaration which represent the method
declaration of format I get the following:

fDeclaration.isVarargs()
	 (boolean) true
fDeclaration.toString()
	 (java.lang.String) public static final String format(String key,Object...
argssss){
  return MessageFormat.format(key,argssss);
}
((SingleVariableDeclaration)fDeclaration.parameters().get(1)).isVarargs()
	 (boolean) true
((SingleVariableDeclaration)fDeclaration.parameters().get(1)).resolveBinding().getType().isArray()
	 (boolean) true
((SingleVariableDeclaration)fDeclaration.parameters().get(1)).toString()
	 (java.lang.String) Object... argssss

I there something I am missing here ?
Comment 16 Olivier Thomann CLA 2005-05-10 10:47:06 EDT
You are getting confused between the type of the binding of the single variable
declaration that is an array and the binding of the type of the single variable
declaration that is not an array.
This is in line with the specs and I don't see anything to change in this area.

((SingleVariableDeclaration)fDeclaration.parameters().get(1)).getType().resolveBinding().isArray()
answers false as expected.
because the type's positions don't include the '...'.

Ok to close?
Comment 17 Olivier Thomann CLA 2005-05-10 12:21:29 EDT
Closing as FIXED since the described problem in comment 10 is not a problem, but
the original problem is indeed fixed.
Comment 18 Dirk Baeumer CLA 2005-05-10 14:52:31 EDT
OK I see. But this is a tricky detail ;-). May be we should add this to the Java
doc.
Comment 19 Olivier Thomann CLA 2005-05-10 15:00:17 EDT
Jim, I let you be the judge to find out if we need anything else in the doc. For
me the isVarArgs() on SingleVariableDeclaration doc is pretty clear.