Bug 22154 - Proposed method for org.eclipse.jdt.core.dom.ITypeBinding
Summary: Proposed method for org.eclipse.jdt.core.dom.ITypeBinding
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: PC All
: P3 enhancement (vote)
Target Milestone: 2.1 M1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-08-04 20:49 EDT by Timothy Halloran CLA
Modified: 2002-09-19 04:37 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Timothy Halloran CLA 2002-08-04 20:49:49 EDT
I think ITypeBinding needs a method "getFullyQualifiedName()".  An exact match 
with org.eclipse.jtd.core.IType's method may make the most sense.

Why:
Using the DOM for analysis you need the fully qualified name many times, and 
generating it properly is not entirly trivial -- if it doesn't exist then 
return "null".

I imagine I am not the only one who "cooked" a routine to get a type's fully 
qualified name.  Below is the code I have been using (it could easly be 
changed into a method for ITypeBinding).  It is a bit simple, but illustrates 
that for nested classes this is not as easy at putinng "getName()" in front of 
the package name.

  /**
   * Returns the fully qualified name for a ITypeBinding or null
   * if the name can't be determined.  Returns the fully qualified
   * name of the element type if the type is an array
   * @param type The binding to determine the fully qualified name for.
   * @return The fully qualified name of the binding.
   */
  public static String fullyQualifiedName(ITypeBinding type) {
    if (type == null) { // check that we really got an ITypeBinding
      return null;
    }
    // if type is anonymous then it doesn't have a name
    if (type.isAnonymous()) {
    	return null;
    }
    // if type is an array get the element type
    ITypeBinding baseType = (type.isArray() ? type.getElementType() : type);
    // add the package name (if one is used)
    IPackageBinding typePackage = baseType.getPackage();
    String result = "";
    if (typePackage != null) {
      if (typePackage.isUnnamed()) {
        String pkgName = typePackage.getName();
        result = pkgName + ".";
      }
    }
  }

Thoughts?

Take Care,
Tim Halloran
CMU
Comment 1 Philipe Mulet CLA 2002-09-03 04:36:00 EDT
This should rather be provided on ITypeBinding directly.

ITypeBinding#getQualifiedName()

It should offer dot separated names; e.g. member class p.A$B would show up 
as: "p.A.B".

Do you agree ?
Comment 2 Timothy Halloran CLA 2002-09-03 10:46:36 EDT
Yes, the code was only an example "hack" we used in one of our plugins.
Comment 3 Olivier Thomann CLA 2002-09-04 13:53:09 EDT
A local class should return null. Is this fine for you?

For example:
class A {
   void foo() {
       class B {
       }
   } 
}

What name do you expect to get for the class B? The VM name would be A$1$B. I
would say null is fine in this case.

Only top level class and member class returns a fully qualified name not null.
Comment 4 Olivier Thomann CLA 2002-09-04 13:56:55 EDT
Is this new API what you expect?

/**
 * Returns the fully qualified name of this type binding if it exists, null
otherwise.
 * 
 * If this type binding represents an anonymous or a local type, then it returns
null.
 * If this type binding represents a member type, then it returns its VM name
preceeded with
 * its package name replacing all '$' with a dot.
 * For example, the member class p.A$B (VM name) is converted to "p.A.B".
 * For a top level type, is returns its name preceeded with its package name.
 * 
 * @return the fully qualified name of this type binding if it exists, null
otherwise.
 */
public String getQualifiedName();
Comment 5 Timothy Halloran CLA 2002-09-05 14:52:31 EDT
Olivier,

Sorry, for the delay, I've been busy with a deadline.
I fully agree with your proposal.  I would propose "lifting" the JavaDoc
from jdt.core.IType.getFullyQualifiedName -- there are two versions (see
below)...looking at this I wonder if getTypeQualifiedName should be added to the
API as well.

My thinking is that jtd.core.dom IBinding* classes should have "parellel" APIs
to jdt.core.IType/method/variable where "reasonable"

I was actually going to do a patch for this one, but if you are working it thats
great!

Take Care,
Tim

FROM jdt.core.IType:

getFullyQualifiedName

public String getFullyQualifiedName()

    Returns the fully qualified name of this type, including qualification for
any containing types and packages. This is the name of the package, followed by
'.', followed by the type-qualified name. This is a handle-only method.

Returns:
the fully qualified name of this typeSee Also:
getTypeQualifiedName()
getFullyQualifiedName

public String getFullyQualifiedName(char enclosingTypeSeparator)

    Returns the fully qualified name of this type, including qualification for
any containing types and packages. This is the name of the package, followed by
'.', followed by the type-qualified name using the enclosingTypeSeparator. For
example:

        * the fully qualified name of a class B defined as a member of a class A
in a compilation unit A.java in a package x.y using the '.' separator is "x.y.A.B"
        * the fully qualified name of a class B defined as a member of a class A
in a compilation unit A.java in a package x.y using the '$' separator is "x.y.A$B"
        * the fully qualified name of a binary type whose class file is
x/y/A$B.class using the '.' separator is "x.y.A.B"
        * the fully qualified name of a binary type whose class file is
x/y/A$B.class using the '$' separator is "x.y.A$B"
        * the fully qualified name of an anonymous binary type whose class file
is x/y/A$1.class using the '.' separator is "x.y.A$1"

    This is a handle-only method.

Parameters:
enclosingTypeSeparator - the given enclosing type separator Returns:
the fully qualified name of this type, including qualification for any
containing types and packagesSince:
2.0See Also:
getTypeQualifiedName(char)
Comment 6 Olivier Thomann CLA 2002-09-05 15:32:12 EDT
I thought that null was fine for an anonymous type. This is not the case if you
want something close to the IType method.
Please let us know what you want for:
- an array type
- a primitive type
- an anonymous type
- a local type
- a member type
- a top-level type
- the null type

I would say:
- an array type => qualified name of the element type followed by pairs of "[]".
- a primitive type => null
- an anonymous type => null
- a local type => null
- a member type => qualified name of the enclosing type followed by '.' + name
of the member type.
- a top-level type => package name + '.' + type name
- the null type = > null


Let me know if I am wrong. I'd like to get this in the next submission from
JDT/Core.
Comment 7 Jim des Rivieres CLA 2002-09-05 16:53:46 EDT
Returning "" instead of null is more consistent with ITypeBinding.getName(),
which is closer than IType.getFullyQualifiedName or getTypeQualifiedName.
I've revised the spec as follows:

	/**
	 * Returns the fully qualified name of the type represented by this 
	 * binding if it has one.
	 * <ul>
	 * <li>For top-level types, the fully qualified name is the simple 
name of
	 * the type qualified by the package name (or unqualified if in a 
default
	 * package).
	 * Example: <code>"java.lang.String"</code>.</li>
	 * <li>For members of top-level types, the fully qualified name is the
	 * simple name of the type qualified by the fully qualified name of the
	 * enclosing type.
	 * Example: <code>"java.io.ObjectInputStream.GetField"</code>.</li>
	 * <li>For primitive types, the fully qualified name is the keyword for
	 * the primitive type.
	 * Example: <code>"int"</code>.</li>
	 * <li>For array types whose component type has a fully qualified 
name, 
	 * the fully qualified name is the fully qualified name of the 
component
	 * type followed by "[]".
	 * Example: <code>"java.lang.String[]"</code>.</li>
	 * <li>For the null type, the fully qualified name is the string 
	 * "null".</li>
	 * <li>Local types (including anonymous classes) and members of local
	 * types do not have a fully qualified name. For these types, and array
	 * types thereof, this method returns an empty string.</li>
	 * </ul>
	 * 
	 * @return the fully qualified name of the type represented by this 
	 *    binding, or an empty string if this type does not have such an
	 *    unambiguous name
	 * @see #getName
	 * @since 2.1
	 */
	public String getQualifiedName();
Comment 8 Olivier Thomann CLA 2002-09-06 13:23:28 EDT
Fixed and released in 2.1 stream.
Comment 9 David Audel CLA 2002-09-19 04:37:35 EDT
Verified.