use of kalang.core.GenericType in project kalang by kasonyang.
the class Ast2Class method classSignature.
@Nullable
private String classSignature(ClassNode c) {
GenericType[] genericTypes = c.getGenericTypes();
if (genericTypes == null || genericTypes.length == 0) {
return null;
}
String gnrTypeStr = "";
for (GenericType t : genericTypes) {
gnrTypeStr += t.getName() + ":" + "Ljava/lang/Object;";
}
String superTypeStr = "";
if (c.getSuperType() != null)
superTypeStr += typeSignature(c.getSuperType());
for (ObjectType itf : c.getInterfaces()) {
superTypeStr += typeSignature(itf);
}
return "<" + gnrTypeStr + ">" + superTypeStr;
}
use of kalang.core.GenericType in project kalang by kasonyang.
the class AstBuilder method getObjectInvokeExpr.
@Nullable
private ExprNode getObjectInvokeExpr(ExprNode target, String methodName, ExprNode[] args, ParserRuleContext ctx) {
if ("<init>".equals(methodName)) {
throw Exceptions.unexceptedException("Don't get constructor by this method.");
}
Type targetType = target.getType();
if (!(targetType instanceof ObjectType)) {
handleSyntaxError("class type required.", ctx);
return null;
}
ObjectType targetClassType = (ObjectType) targetType;
if (targetClassType.getNullable() == NullableKind.NULLABLE) {
handleSyntaxError("expression may be null", ctx);
return null;
}
ExprNode expr;
try {
ObjectInvokeExpr invoke = ObjectInvokeExpr.create(target, methodName, args, thisClazz);
if (invoke.getMethod().getMethodNode().getType() instanceof GenericType) {
Type invokeType = invoke.getType();
if (invokeType instanceof ObjectType) {
expr = new CastExpr(invokeType, invoke);
} else {
expr = invoke;
}
} else {
expr = invoke;
}
} catch (MethodNotFoundException ex) {
methodNotFound(ctx.start, className, methodName, args);
expr = new UnknownInvocationExpr(target, methodName, args);
} catch (AmbiguousMethodException ex) {
methodIsAmbiguous(ctx.start, ex);
return null;
}
mapAst(expr, ctx);
return expr;
}
use of kalang.core.GenericType in project kalang by kasonyang.
the class ClassNodeMetaBuilder method visitClassDef.
@Override
public Object visitClassDef(KalangParser.ClassDefContext ctx) {
thisClazz.annotations.addAll(astBuilder.getAnnotations(ctx.annotation()));
thisClazz.modifier = astBuilder.parseModifier(ctx.varModifier());
List<Token> gnrTypes = ctx.genericTypes;
if (gnrTypes != null && !gnrTypes.isEmpty()) {
for (Token g : gnrTypes) {
// TODO suport generic type bounds in syntax
GenericType gt = new GenericType(g.getText(), Types.getRootType(), null, NullableKind.NONNULL);
thisClazz.declareGenericType(gt);
}
}
ObjectType superType = null;
if (ctx.parentClass != null) {
ObjectType parentClass = astBuilder.parseClassType(ctx.parentClass);
if (parentClass != null) {
superType = parentClass;
}
} else {
superType = Types.getRootType();
}
if (Modifier.isInterface(thisClazz.modifier)) {
// TODO update syntax to support:interface extends T1,T2...
thisClazz.addInterface(superType);
} else {
thisClazz.setSuperType(superType);
}
if (ctx.interfaces != null && ctx.interfaces.size() > 0) {
for (KalangParser.ClassTypeContext itf : ctx.interfaces) {
ObjectType itfClz = astBuilder.parseClassType(itf);
if (itfClz != null) {
thisClazz.addInterface(itfClz);
}
}
}
if (this.isDeclaringNonStaticInnerClass()) {
ClassNode parentClass = thisClazz.enclosingClass;
if (parentClass == null) {
throw Exceptions.unexceptedValue(parentClass);
}
thisClazz.createField(Types.getClassType(parentClass), "this$0", Modifier.PRIVATE | ModifierConstant.SYNTHETIC);
}
visit(ctx.classBody());
if (!ModifierUtil.isInterface(thisClazz.modifier) && !AstUtil.containsConstructor(thisClazz) && !AstUtil.createEmptyConstructor(thisClazz)) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "failed to create constructor with no parameters", ctx);
}
MethodNode[] methods = thisClazz.getDeclaredMethodNodes();
for (int i = 0; i < methods.length; i++) {
MethodNode node = methods[i];
BlockStmt body = node.getBody();
if (body != null) {
if (AstUtil.isConstructor(node)) {
// constructor
if (this.isDeclaringNonStaticInnerClass()) {
ClassNode enclosingClass = thisClazz.enclosingClass;
if (enclosingClass == null) {
throw Exceptions.unexceptedValue(enclosingClass);
}
ParameterNode outerInstanceParam = node.createParameter(0, Types.getClassType(enclosingClass), "this$0");
ExprNode parentFieldExpr = astBuilder.getObjectFieldExpr(new ThisExpr(Types.getClassType(thisClazz)), "this$0", ParserRuleContext.EMPTY);
if (parentFieldExpr == null) {
throw Exceptions.unexceptedValue(parentFieldExpr);
}
body.statements.add(1, new ExprStmt(new AssignExpr((AssignableExpr) parentFieldExpr, new ParameterExpr(outerInstanceParam))));
}
}
}
}
for (FieldNode fieldNode : thisClazz.getFields()) {
int mdf = fieldNode.modifier;
if (!AstUtil.hasGetter(thisClazz, fieldNode)) {
AstUtil.createGetter(thisClazz, fieldNode, mdf);
}
if (!AstUtil.hasSetter(thisClazz, fieldNode)) {
AstUtil.createSetter(thisClazz, fieldNode, mdf);
}
fieldNode.modifier = ModifierUtil.setPrivate(mdf);
}
return null;
}
use of kalang.core.GenericType in project kalang by kasonyang.
the class JvmClassNode method transType.
// TODO why transType could be null?
@Nullable
private Type transType(java.lang.reflect.Type t, Map<TypeVariable, GenericType> genericTypes) {
if (t instanceof TypeVariable) {
GenericType vt = genericTypes.get((TypeVariable) t);
// FIXME it may be null if TypeVariable comes from method
if (vt != null) {
return vt;
}
return null;
} else if (t instanceof java.lang.reflect.ParameterizedType) {
java.lang.reflect.ParameterizedType pt = (java.lang.reflect.ParameterizedType) t;
Type rawType = transType(pt.getRawType(), genericTypes);
if (!(rawType instanceof ObjectType)) {
return null;
}
java.lang.reflect.Type[] typeArgs = pt.getActualTypeArguments();
Type[] gTypes = transType(typeArgs, genericTypes);
if (gTypes == null) {
return null;
}
return Types.getClassType(((ObjectType) rawType).getClassNode(), gTypes);
} else if (t instanceof java.lang.reflect.WildcardType) {
java.lang.reflect.WildcardType wt = (java.lang.reflect.WildcardType) t;
Type[] upperBounds = transType(wt.getUpperBounds(), genericTypes);
if (upperBounds == null) {
return null;
}
Type[] lowerBounds = transType(wt.getLowerBounds(), genericTypes);
if (lowerBounds == null) {
return null;
}
return new WildcardType(upperBounds, lowerBounds);
} else if (t instanceof GenericArrayType) {
GenericArrayType gt = (GenericArrayType) t;
Type ct = transType(gt.getGenericComponentType(), genericTypes);
if (ct == null) {
return null;
}
return Types.getArrayType(ct, NullableKind.NONNULL);
} else if (t instanceof Class) {
Class type = (Class) t;
if (type.isPrimitive()) {
return Types.getPrimitiveType(type.getTypeName());
} else if (type.isArray()) {
Type ct = transType(type.getComponentType(), genericTypes);
if (ct == null) {
return null;
}
return Types.getArrayType(ct);
} else {
try {
return Types.getClassType(this.astLoader.findAst(type));
} catch (AstNotFoundException ex) {
throw new RuntimeException(ex);
}
}
} else {
return null;
}
}
use of kalang.core.GenericType in project kalang by kasonyang.
the class TypeUtil method equalTypes.
public static boolean equalTypes(Type[] declaredTypes, Type[] argTypes, @Nullable Map<GenericType, Type> genericTypes) {
if (declaredTypes.length != argTypes.length)
return false;
if (declaredTypes.length == 0)
return true;
for (int i = 0; i < declaredTypes.length; i++) {
Type dt = declaredTypes[i];
if (dt instanceof GenericType) {
if (genericTypes != null) {
dt = genericTypes.get((GenericType) dt);
Objects.requireNonNull(dt);
}
}
if (!equalType(dt, argTypes[i], genericTypes))
return false;
}
return true;
}
Aggregations