com.sun.codemodel.JClass Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.codemodel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* Represents a Java reference type, such as a class, an interface,
* an enum, an array type, a parameterized type.
*
*
* To be exact, this object represents an "use" of a reference type,
* not necessarily a declaration of it, which is modeled as {@link JDefinedClass}.
*/
public abstract class JClass extends JType
{
protected JClass( JCodeModel _owner ) {
this._owner = _owner;
}
/**
* Gets the name of this class.
*
* @return
* name of this class, without any qualification.
* For example, this method returns "String" for
* java.lang.String
.
*/
abstract public String name();
/**
* Gets the package to which this class belongs.
* TODO: shall we move move this down?
*/
abstract public JPackage _package();
/**
* Returns the class in which this class is nested, or null if
* this is a top-level class.
*/
public JClass outer() {
return null;
}
private final JCodeModel _owner;
/** Gets the JCodeModel object to which this object belongs. */
public final JCodeModel owner() { return _owner; }
/**
* Gets the super class of this class.
*
* @return
* Returns the JClass representing the superclass of the
* entity (class or interface) represented by this {@link JClass}.
* Even if no super class is given explicitly or this {@link JClass}
* is not a class, this method still returns
* {@link JClass} for {@link Object}.
* If this JClass represents {@link Object}, return null.
*/
abstract public JClass _extends();
/**
* Iterates all super interfaces directly implemented by
* this class/interface.
*
* @return
* A non-null valid iterator that iterates all
* {@link JClass} objects that represents those interfaces
* implemented by this object.
*/
abstract public Iterator _implements();
/**
* Iterates all the type parameters of this class/interface.
*
*
* For example, if this {@link JClass} represents
* Set<T>
, this method returns an array
* that contains single {@link JTypeVar} for 'T'.
*/
public JTypeVar[] typeParams() {
return EMPTY_ARRAY;
}
/**
* Sometimes useful reusable empty array.
*/
protected static final JTypeVar[] EMPTY_ARRAY = new JTypeVar[0];
/**
* Checks if this object represents an interface.
*/
abstract public boolean isInterface();
/**
* Checks if this class is an abstract class.
*/
abstract public boolean isAbstract();
/**
* If this class represents one of the wrapper classes
* defined in the java.lang package, return the corresponding
* primitive type. Otherwise null.
*/
public JPrimitiveType getPrimitiveType() { return null; }
/**
* @deprecated calling this method from {@link JClass}
* would be meaningless, since it's always guaranteed to
* return this.
*/
public JClass boxify() { return this; }
public JType unboxify() {
JPrimitiveType pt = getPrimitiveType();
return pt==null ? (JType)this : pt;
}
public JClass erasure() {
return this;
}
/**
* Checks the relationship between two classes.
*
* This method works in the same way as {@link Class#isAssignableFrom(Class)}
* works. For example, baseClass.isAssignableFrom(derivedClass)==true.
*/
public final boolean isAssignableFrom( JClass derived ) {
// to avoid the confusion, always use "this" explicitly in this method.
// null can be assigned to any type.
if( derived instanceof JNullType ) return true;
if( this==derived ) return true;
// the only class that is assignable from an interface is
// java.lang.Object
if( this==_package().owner().ref(Object.class) ) return true;
JClass b = derived._extends();
if( b!=null && this.isAssignableFrom(b) )
return true;
if( this.isInterface() ) {
Iterator itfs = derived._implements();
while( itfs.hasNext() )
if( this.isAssignableFrom(itfs.next()) )
return true;
}
return false;
}
/**
* Gets the parameterization of the given base type.
*
*
* For example, given the following
*
* interface Foo extends List> {}
* interface Bar extends Foo {}
*
* This method works like this:
*
* getBaseClass( Bar, List ) = List
* getBaseClass( Bar, Foo ) = Foo
* getBaseClass( Foo extends Number>, Collection ) = Collection>
* getBaseClass( ArrayList extends BigInteger>, List ) = List extends BigInteger>
*
*
* @param baseType
* The class whose parameterization we are interested in.
* @return
* The use of {@code baseType} in {@code this} type.
* or null if the type is not assignable to the base type.
*/
public final JClass getBaseClass( JClass baseType ) {
if( this.erasure().equals(baseType) )
return this;
JClass b = _extends();
if( b!=null ) {
JClass bc = b.getBaseClass(baseType);
if(bc!=null)
return bc;
}
Iterator itfs = _implements();
while( itfs.hasNext() ) {
JClass bc = itfs.next().getBaseClass(baseType);
if(bc!=null)
return bc;
}
return null;
}
public final JClass getBaseClass( Class> baseType ) {
return getBaseClass(owner().ref(baseType));
}
private JClass arrayClass;
public JClass array() {
if(arrayClass==null)
arrayClass = new JArrayClass(owner(),this);
return arrayClass;
}
/**
* "Narrows" a generic class to a concrete class by specifying
* a type argument.
*
*
* .narrow(X)
builds Set<X>
from Set
.
*/
public JClass narrow( Class> clazz ) {
return narrow(owner().ref(clazz));
}
public JClass narrow( Class>... clazz ) {
JClass[] r = new JClass[clazz.length];
for( int i=0; i
* .narrow(X)
builds Set<X>
from Set
.
*/
public JClass narrow( JClass clazz ) {
return new JNarrowedClass(this,clazz);
}
public JClass narrow( JType type ) {
return narrow(type.boxify());
}
public JClass narrow( JClass... clazz ) {
return new JNarrowedClass(this,Arrays.asList(clazz.clone()));
}
public JClass narrow( List extends JClass> clazz ) {
return new JNarrowedClass(this,new ArrayList(clazz));
}
/**
* If this class is parameterized, return the type parameter of the given index.
*/
public List getTypeParameters() {
return Collections.emptyList();
}
/**
* Returns true if this class is a parameterized class.
*/
public final boolean isParameterized() {
return erasure()!=this;
}
/**
* Create "? extends T" from T.
*
* @return never null
*/
public final JClass wildcard() {
return new JTypeWildcard(this);
}
/**
* Substitutes the type variables with their actual arguments.
*
*
* For example, when this class is Map<String,Map<V>>,
* (where V then doing
* substituteParams( V, Integer ) returns a {@link JClass}
* for Map<String,Map<Integer>>
.
*
*
* This method needs to work recursively.
*/
protected abstract JClass substituteParams( JTypeVar[] variables, List bindings );
public String toString() {
return this.getClass().getName() + '(' + name() + ')';
}
public final JExpression dotclass() {
return JExpr.dotclass(this);
}
/** Generates a static method invocation. */
public final JInvocation staticInvoke(JMethod method) {
return new JInvocation(this,method);
}
/** Generates a static method invocation. */
public final JInvocation staticInvoke(String method) {
return new JInvocation(this,method);
}
/** Static field reference. */
public final JFieldRef staticRef(String field) {
return new JFieldRef(this, field);
}
/** Static field reference. */
public final JFieldRef staticRef(JVar field) {
return new JFieldRef(this, field);
}
public void generate(JFormatter f) {
f.t(this);
}
/**
* Prints the class name in javadoc @link format.
*/
void printLink(JFormatter f) {
f.p("{@link ").g(this).p('}');
}
}