/*
* Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package visage.reflect;
import java.lang.reflect.*;
import java.lang.annotation.Annotation;
import org.visage.runtime.annotation.*;
import org.visage.runtime.annotation.Package;
/**
* Helper methods to factor out functionality only available on J2SE.
* @author Per Bothner
*/
class PlatformUtils {
static Type[] getGenericParameterTypes(Method m) {
return m.getGenericParameterTypes();
}
static Type getGenericReturnType(Method m) {
return m.getGenericReturnType();
}
static boolean isSynthetic(Field fld) {
return fld.isSynthetic();
}
static boolean isSynthetic(Method m) {
return m.isSynthetic();
}
static int checkInherited(Method m) {
return m.getAnnotation(org.visage.runtime.annotation.Inherited.class) != null ? 1 : 0;
}
static String getCanonicalName(Class cls) {
return cls.getCanonicalName();
}
static String getSourceNameFromAnnotation(Field fld) {
SourceName sname = fld.getAnnotation(SourceName.class);
return sname == null ? null : sname.value();
}
static Annotation getAnnotation (VisageLocal.ClassType ctype, Class clas) {
Class cls = ctype.refClass;
return cls.getAnnotation(clas);
}
static <T extends Annotation> T getAnnotation (VisageLocal.VarMember vmem, Class<T> clas) {
Field fld = vmem.fld;
if (fld != null)
return fld.getAnnotation(clas);
Method getter = vmem.getter;
if (getter != null)
return getter.getAnnotation(clas);
return null;
}
static int checkPublic(VisageLocal.ClassType ctype) {
if (ctype.isVisageType())
return -1;
return getAnnotation(ctype, Public.class) != null ? 1 : 0;
}
static int checkPackage(VisageLocal.ClassType ctype) {
if (! ctype.isVisageType())
return -1;
return getAnnotation(ctype, Package.class) != null ? 1 : 0;
}
static boolean isProtected(VisageLocal.ClassType ctype) {
return getAnnotation(ctype, Protected.class) != null;
}
static int checkAccess(VisageLocal.VarMember vmem, Class ann) {
if (! vmem.getDeclaringClass().isVisageType())
return -1;
return getAnnotation(vmem, ann) != null ? 1 : 0;
}
static boolean checkAccessAnnotations(VisageLocal.VarMember vmem) {
if (getAnnotation(vmem, Public.class) != null)
vmem.flags |= VisageLocal.VarMember.IS_PUBLIC;
if (getAnnotation(vmem, Protected.class) != null)
vmem.flags |= VisageLocal.VarMember.IS_PROTECTED;
if (getAnnotation(vmem, Package.class) != null)
vmem.flags |= VisageLocal.VarMember.IS_PACKAGE;
if (getAnnotation(vmem, PublicInitable.class) != null)
vmem.flags |= VisageLocal.VarMember.IS_PUBLIC_INIT;
if (getAnnotation(vmem, PublicReadable.class) != null)
vmem.flags |= VisageLocal.VarMember.IS_PUBLIC_READ;
return true;
}
static int checkDef(VisageLocal.VarMember vmem) {
return checkAccess(vmem, Def.class);
}
static int checkAccess(VisageLocal.FunctionMember fmem, Class ann) {
if (! fmem.getDeclaringClass().isVisageType())
return -1;
return fmem.method.getAnnotation(ann) != null ? 1 : 0;
}
static int checkPublic(VisageLocal.FunctionMember fmem) {
return checkAccess(fmem, Public.class);
}
static int checkProtected(VisageLocal.FunctionMember fmem) {
return checkAccess(fmem, Protected.class);
}
static int checkPackage(VisageLocal.FunctionMember fmem) {
return checkAccess(fmem, Package.class);
}
// Return either an VisageType, if resolved, or a Type (which
// the same as typ, though possibly "simplified".
static Object resolveGeneric (VisageLocal.Context context, Type typ) {
if (typ instanceof ParameterizedType) {
ParameterizedType ptyp = (ParameterizedType) typ;
Type raw = ptyp.getRawType();
Type[] targs = ptyp.getActualTypeArguments();
if (raw instanceof Class) {
String rawName = ((Class) raw).getName();
if (VisageClassType.SEQUENCE_CLASSNAME.equals(rawName) &&
targs.length == 1) {
return new VisageSequenceType(context.makeTypeRef(targs[0]));
}
if (VisageClassType.OBJECT_VARIABLE_CLASSNAME.equals(rawName) &&
targs.length == 1) {
return context.makeTypeRef(targs[0]);
}
if (VisageClassType.SEQUENCE_VARIABLE_CLASSNAME.equals(rawName) &&
targs.length == 1) {
return new VisageSequenceType(context.makeTypeRef(targs[0]));
}
if (rawName.startsWith(VisageClassType.FUNCTION_CLASSNAME_PREFIX)) {
VisageType[] prtypes = new VisageType[targs.length-1];
for (int i = prtypes.length; --i >= 0; )
prtypes[i] = context.makeTypeRef(targs[i+1]);
VisageType rettype;
if (targs[0] == java.lang.Void.class)
rettype = VisagePrimitiveType.voidType;
else
rettype = context.makeTypeRef(targs[0]);
return new VisageFunctionType(prtypes, rettype);
}
}
typ = raw;
}
if (typ instanceof WildcardType) {
WildcardType wtyp = (WildcardType) typ;
Type[] upper = wtyp.getUpperBounds();
Type[] lower = wtyp.getLowerBounds();
typ = lower.length > 0 ? lower[0] : wtyp.getUpperBounds()[0];
if (typ instanceof Class) {
String rawName = ((Class) typ).getName();
// Kludge, because generics don't handle primitive types.
VisageType ptype = context.getPrimitiveType(rawName);
if (ptype != null)
return ptype;
}
return context.makeTypeRef(typ);
}
if (typ instanceof GenericArrayType) {
VisageType elType = context.makeTypeRef(((GenericArrayType) typ).getGenericComponentType());
return new VisageJavaArrayType(elType);
}
if (typ instanceof TypeVariable) {
// KLUDGE
typ = Object.class;
}
return typ;
}
}